动态逆序对[CDQ分治]

题面
luogu

cdq分治入门
注意删的是值不是位置!


#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
const int N = 1e5 + 5;
const int inf = 0x3f3f3f3f;
struct Node{
    int x, y, z;
    long long cnt;
}node[N];
inline bool rule_xyz(Node x, Node y){
    if(x.x != y.x) return x.x < y.x;
    if(x.y != y.y) return x.y < y.y;
    return x.z < y.z;
}
inline bool rule_yzx(Node x, Node y){
    if(x.y != y.y) return x.y < y.y;
    if(x.z != y.z) return x.z < y.z;
    return x.x < y.x;
}
int n, m, a[N], b[N];

inline void debug(int L, int R){
    for(int i = L; i <= R; ++i){
        if(node[i].x == 1){
            printf("debug %lld
", node[i].cnt);
            break;	
        }	
    }	
}

struct BIT{
    int w[N];
    void ins(int x, int d){
        while(x <= n){w[x] += d; x += x & -x;}
    }
    int qry(int x){
        int res = 0;
        while(x){res += w[x]; x -= x & -x;}
        return res;
    }
    void print(){
        for(int i = 1; i <= n; ++i) printf("%d ", w[i]);
        printf("
");	
    }
}bit;

void cdq(int L, int R){
    if(L >= R) return ;
    int mid = L + ((R - L) >> 1);
    cdq(L, mid); cdq(mid + 1, R);	
    sort(node + L, node + mid + 1, rule_yzx);
    sort(node + mid + 1, node + R + 1, rule_yzx);
    int j = mid + 1;
    for(int i = L; i <= mid; ++i){
        while(j <= R && node[j].y < node[i].y){
            bit.ins(node[j].z, 1); ++j;
        } 
        node[i].cnt += bit.qry(n) - bit.qry(node[i].z);
    }
    while(--j >= mid + 1){bit.ins(node[j].z, -1);}
    
    j = R;
    for(int i = mid; i >= L; --i){
        while(j >= mid + 1 && node[j].y > node[i].y){
            bit.ins(node[j].z, 1); --j;
        }
        node[i].cnt += bit.qry(node[i].z - 1);
    }
    while(++j <= R) {bit.ins(node[j].z, -1);}
    //printf("%d %d
", L, R); 
    //bit.print();
    //if(L <= 1) debug(L, R);
}

int main(){
    //freopen();
    scanf("%d%d", &n, &m); 
    for(int i = 1; i <= n; ++i){
        scanf("%d", &a[i]);
        b[a[i]] = i;	
    }
    for(int i = 1; i <= n; ++i) 
        node[i] = (Node){inf, i, a[i], 0};	
    for(int i = 1, x; i <= m; ++i){
        scanf("%d", &x);
        node[b[x]].x = i;//注意审题哦 这里是删掉为x的值
    } 
    
    sort(node + 1, node + n + 1, rule_xyz);
    cdq(1, n);
    sort(node + 1, node + n + 1, rule_xyz);
    
    long long ans = 0;
    for(int i = n; i >= 1; --i){
        ans += bit.qry(a[i]);
        bit.ins(a[i], 1);
    }
    for(int i = 1; i <= m; ++i){
        printf("%lld
", ans);
        ans -= node[i].cnt;
    }
    return 0;	
}
原文地址:https://www.cnblogs.com/hjmmm/p/10647447.html