树状数组RE,线段树AC,求调/(ㄒoㄒ)/~~
查看原帖
树状数组RE,线段树AC,求调/(ㄒoㄒ)/~~
815075
hzy99999楼主2024/7/10 10:57

树状数组RE代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int n;
int a[N];
int tr0[N];
struct Node
{
    int l, r, max;
} tr[N * 4];
void pushup(int u)
{
    tr[u].max = max(tr[u << 1].max, tr[u << 1 | 1].max);
}
void build(int u, int l, int r)
{
    tr[u] = {l, r, 0};
    if (l == r)
    {
        tr[u].max = l;
        return;
    }
    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
    pushup(u);
}
void modify(int u, int x, int d)
{
    int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
    if (l == r)
    {
        tr[u].max = d;
        return;
    }
    if (x <= mid)
        modify(u << 1, x, d);
    else
        modify(u << 1 | 1, x, d);
    pushup(u);
}
int query(int u, int x, int y)
{
    int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
    if (x <= l && r <= y)
        return tr[u].max;
    int res = 0;
    if (x <= mid)
        res = max(res, query(u << 1, x, y));
    if (y > mid)
        res = max(res, query(u << 1 | 1, x, y));
    return res;
}
int lowbit(int x)
{
    return x & -x;
}
int add(int x, int d)
{
    for (int i = x; i <= n; i += lowbit(i))
        tr0[i] += d;
}
int find(int x)
{
    int res = 0;
    for (int i = x; i; i -= lowbit(i))
        res += tr0[i];
    return res;
}
int main()
{
    scanf("%d", &n);
    build(1, 1, n);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = n; i; i--)
    {
        a[i] = query(1, 1, a[i]);
        if (!a[i])
        {
            printf("-1\n");
            return 0;
        }
        modify(1, a[i], 0);
    }

    // for (int i = 1; i <= n; i++)
    //     printf("%d ", a[i]);
    // puts("");

    LL ans = 0;
    for (int i = 1; i <= n; i++)
    {
        add(a[i], 1);
        ans += find(n) - find(a[i]);
    }
    printf("%lld\n", ans);
    return 0;
}

线段树AC代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int n;
int a[N];
int tr0[N];
struct Node
{
    int l, r, tag;
} tr1[N * 4], tr2[N * 4];
void pushup(Node tr[], int u, int type)
{
    if (!type)
        tr[u].tag = max(tr[u << 1].tag, tr[u << 1 | 1].tag);
    else
        tr[u].tag = tr[u << 1].tag + tr[u << 1 | 1].tag;
}
void build(Node tr[], int u, int l, int r, int type)
{
    tr[u] = {l, r, 0};
    if (l == r)
    {
        if (!type)
            tr[u].tag = l;
        return;
    }
    int mid = l + r >> 1;
    build(tr, u << 1, l, mid, type), build(tr, u << 1 | 1, mid + 1, r, type);
    pushup(tr, u, type);
}
void modify(Node tr[], int u, int x, int d, int type)
{
    int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
    if (l == r)
    {
        if (!type)
            tr[u].tag = d;
        else
            tr[u].tag += d;
        return;
    }
    if (x <= mid)
        modify(tr, u << 1, x, d, type);
    else
        modify(tr, u << 1 | 1, x, d, type);
    pushup(tr, u, type);
}
int query(Node tr[], int u, int x, int y, int type)
{
    int l = tr[u].l, r = tr[u].r, mid = l + r >> 1;
    if (x <= l && r <= y)
        return tr[u].tag;
    int res = 0;
    if (x <= mid)
        if (!type)
            res = max(res, query(tr, u << 1, x, y, type));
        else
            res += query(tr, u << 1, x, y, type);
    if (y > mid)
        if (!type)
            res = max(res, query(tr, u << 1 | 1, x, y, type));
        else
            res += query(tr, u << 1 | 1, x, y, type);
    return res;
}
int main()
{
    scanf("%d", &n);
    build(tr1, 1, 1, n, 0);
    for (int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    for (int i = n; i; i--)
    {
        a[i] = query(tr1, 1, 1, a[i], 0);
        if (!a[i])
        {
            printf("-1\n");
            return 0;
        }
        modify(tr1, 1, a[i], 0, 0);
    }

    LL ans = 0;
    build(tr2, 1, 1, n, 1);
    for (int i = 1; i <= n; i++)
    {
        modify(tr2, 1, a[i], 1, 1);
        ans += query(tr2, 1, 1, n, 1) - query(tr2, 1, 1, a[i], 1);
    }
    printf("%lld\n", ans);
    return 0;
}

不同点就在于确定好顺序后求逆序对的那一部分

2024/7/10 10:57
加载中...