题意:给一个1 ~ n的排列,有m次删除操作,问每次删除前该序列有多少逆序对
思路:预处理原来总共有多少逆序对,树状数组即可,求出以每个数为逆序对有多少个,删除的时候,先用剩余的逆序对数减去以该数形成的逆序对数,然后看删除的数有多少与该数形成逆序对,再加回去,可以使用分块的方法,快速查询有多少删除的数与其形成逆序对,每次删除的数加在一个新数组上,对新数组分块查找就行了
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long ll;
const int maxn = 2 * 1e5 + 10;
const int sz = 2345;
using namespace std;
int block[maxn / sz + 1][sz];
int a[maxn], id[maxn];
int inv[maxn];
int C[maxn];
int n, m, d;
int query(int l, int r, int v, int op) {
if(l > r) return 0;
int lb = l / sz, rb = r / sz;
int k1 = 0, k2 = 0;
if(lb == rb) {
for(int i = l; i <= r; i++) {
if(a[i] && a[i] < v) k1++;
if(a[i] > v) k2++;
}
} else {
for(int i = l; i < (lb + 1) * sz; i++) {
if(a[i] && a[i] < v) k1++;
if(a[i] > v) k2++;
}
for(int i = rb * sz; i <= r; i++) {
if(a[i] && a[i] < v) k1++;
if(a[i] > v) k2++;
}
for(int b = lb + 1; b < rb; b++) {
int c1 = lower_bound(block[b], block[b] + sz, v) - block[b];
int c2 = upper_bound(block[b], block[b] + sz, 0) - lower_bound(block[b], block[b] + sz, 0);
k1 += c1 - c2;
int ind = upper_bound(block[b], block[b] + sz, v) - block[b];
k2 += sz - ind;
}
}
if(op == 1) return k1;
if(op == 2) return k2;
}
void update(int p, int x) {
if(a[p] == x) return ;
int old = a[p], pos = 0, *B = &block[p / sz][0];
a[p] = x;
while(B[pos] < old) pos++; B[pos] = x;
if(x > old) {
while(pos < sz - 1 && B[pos] > B[pos + 1]) {
swap(B[pos], B[pos + 1]); pos++;
}
} else {
while(pos && B[pos] < B[pos - 1]) {
swap(B[pos], B[pos - 1]); pos--;
}
}
}
int sum(int *C, int i) {
int c = 0;
while(i) {
c += C[i];
i -= i & -i;
}
return c;
}
void update(int *C, int i) {
while(i <= n) {
C[i]++;
i += i & -i;
}
}
int main() {
while(scanf("%d %d", &n, &m) != EOF) {
memset(inv, 0, sizeof inv);
memset(C, 0, sizeof C);
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
id[a[i]] = i;
}
ll tal = 0;
for(int i = n; i >= 1; i--) {
int g = sum(C, a[i] - 1);
tal += g;
inv[i] += g;
inv[i] += i + g - a[i];
update(C, a[i]);
}
memset(a, 0, sizeof a);
while(m--) {
printf("%lld\n",tal);
scanf("%d", &d);
tal -= inv[id[d]];
tal += query(id[d] + 1, n, d, 1);
tal += query(1, id[d] - 1, d, 2);
update(id[d], d);
}
}
return 0;
}