萌新刚学线段树,40pts求调

P1908 逆序对

LYBAKIOI @ 2022-10-06 16:10:54

#include <bits/stdc++.h>

#define int long long

using namespace std;

int read() {
    int x = 0, k = 1;
    char c = getchar();
    while (c < '0' || c > '9') {
        if (c == '-') k = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9') {
        x = x * 10 + c - '0';
        c = getchar();
    }
    return x * k;
}

#define N 500005

struct node {
    int x, id;
    friend bool operator < (const node a, const node b) {
        return a.x < b.x;
    }
} t[N];

struct segt {
    int l, r, dat;
} a[N << 2];

namespace segment_tree {

    void build(int p, int l, int r) {
        a[p].l = l; a[p].r = r;
        if (l == r) return ;
        int mid = l + r >> 1;
        build(p << 1, l, mid);
        build(p << 1 | 1, mid + 1, r);
    }

    int query(int p, int l, int r) {
        if (a[p].l >= l && a[p].r <= r) return a[p].dat;
        int mid = a[p].l + a[p].r >> 1, sum = 0;
        if (l <= mid) sum += query(p << 1, l, r);
        if (r > mid) sum += query(p << 1 | 1, l, r);
        return sum;
    }

    void update(int p, int w, int x) {
        if (a[p].l == w && a[p].r == w) {
            a[p].dat += x; return ;
        }
        int mid = a[p].l + a[p].r >> 1;
        if (w <= mid) update(p << 1, w, x);
        else update(p << 1 | 1, w, x);
        a[p].dat = a[p << 1].dat + a[p << 1 | 1].dat; 
    }

}

using namespace segment_tree;

int n, d[N];
long long ans;

signed main() {
//  freopen("input.txt", "r", stdin);
//  freopen("output.txt", "w", stdout);
    n = read();
    for (int i = 1; i <= n; i++)
        t[i] = {read(), i};
    sort(t + 1, t + n + 1);
    for (int i = 1; i <= n; i++)
        d[t[i].id] = i;

    build(1, 1, n);
    for (int i = 1; i <= n; i++) {
        ans += query(1, d[i] + 1, n);
        update(1, d[i], 1);
    }
    printf("%lld", ans);
}

rt,第 6 个点就错,发现输出比答案大了 2。


by bamboo12345 @ 2022-10-06 16:26:09

@LYBAKIOI 可能有重复数字,你这样统计的话相同的也会计算


by LYBAKIOI @ 2022-10-06 16:38:38

感谢楼上!sort是不稳定排序,可能会改变相同元素的相对位置(恍然大雾)。

struct node {
    int x, id;
    friend bool operator < (const node a, const node b) {
        if (a.x == b.x) return a.id < b.id;
        return a.x < b.x;
    }
} t[N];

by Kniqht @ 2022-10-07 21:46:32

大佬们都不屑于用树状数组/kk


by x1uc @ 2022-10-30 09:38:13

感谢!


|