其他分享
首页 > 其他分享> > 【数据结构】CF1416C - XOR Inverse

【数据结构】CF1416C - XOR Inverse

作者:互联网

链接:https://codeforces.com/contest/1416/problem/C

显然是要从最高位往下贪。有个暴力的做法是每一层套一个树状数组求逆序对,然后愉快的TLE了。

优化的办法是每一次要利用上一次的信息(反过来的基数排序),总的来说是这样:

第29位:全区间排序
第28位:分高位为 \(\{0,1\}\) 分别排序
第27位:分高位为 \(\{00,01,10,11\}\) 分别排序
第26位:分高位为 \(\{000,001,010,011,100,101,110,111\}\) 分别排序

做到“分别排序”这个功能,每次取出一段连续的高位相同的区间,即可。

int n;
int a[300005];
int b[300005];

void solve() {
    scanf("%d", &n);
    for(int i = 1; i <= n; ++i)
        scanf("%d", &a[i]);

    ll ans = 0;
    int x = 0, highmask = (1 << 30);
    for(int bit = 29; bit >= 0; --bit) {
        ll sum0 = 0, sum1 = 0;
        int curmask = (1 << bit);
        for(int l = 1, r; l <= n; l = r + 1) {
            for(r = l; r + 1 <= n && (a[r]&highmask) == (a[r + 1]&highmask); ++r);
            int cnt0 = 0, cnt1 = 0;
            for(int i = l; i <= r; ++i) {
                if(a[i]&curmask) {
                    ++cnt1;
                    sum1 += cnt0;
                } else {
                    ++cnt0;
                    sum0 += cnt1;
                }
            }
        }
        if(sum0 <= sum1) {
            ans += sum0;
            int btop = 0;
            for(int l = 1, r; l <= n; l = r + 1) {
                for(r = l; r + 1 <= n && (a[r]&highmask) == (a[r + 1]&highmask); ++r);
                for(int i = l; i <= r; ++i) {
                    if(!(a[i]&curmask))
                        b[++btop] = a[i];
                }
                for(int i = l; i <= r; ++i) {
                    if((a[i]&curmask))
                        b[++btop] = a[i];
                }
            }
        } else {
            ans += sum1;
            x |= curmask;
            int btop = 0;
            for(int l = 1, r; l <= n; l = r + 1) {
                for(r = l; r + 1 <= n && (a[r]&highmask) == (a[r + 1]&highmask); ++r);
                for(int i = l; i <= r; ++i) {
                    if((a[i]&curmask))
                        b[++btop] = a[i] ^ curmask;
                }
                for(int i = l; i <= r; ++i) {
                    if(!(a[i]&curmask))
                        b[++btop] = a[i] ^ curmask;
                }
            }
        }
        highmask |= curmask;
        for(int i = 1; i <= n; ++i)
            a[i] = b[i];
    }

    printf("%lld %d\n", ans, x);
    return;
}

标签:Inverse,XOR,高位,int,CF1416C,分别,300005,排序
来源: https://www.cnblogs.com/purinliang/p/13742779.html