题意:
给你n 个数的排列,和q 个操作,每个操作删除一个数,在删除每个数之前 输出当前的逆序对。
思路:
动态逆序对一般用分块乱怼一波就好了。
建立两个分块,一个存有序的数,另一个是未排序的。
删除x的话, 把x 不在的分块直接二分 找 大于x的数 和小于x的数。
对于x 在的分块,直接o(sqrt n)查询一下就好。
注意有序vector 和无序vector的删除,这里傻笔了,wa了一发。
一开始 先用一个树状数组求一边逆序对即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
typedef long long LL;
const int maxn = 200000 + 10;
int a[maxn];
int n,q;
int L[1000];
int R[1000];
vector<int>bit[1000];
vector<int>bit2[1000];
int belong[maxn], block, num, fid[maxn];
void init(){
for (int i = 0; i < 1000; ++i)bit[i].clear(),bit2[i].clear();
block = sqrt(n);
num = n / block;
if (n % block) ++num;
for (int i = 1; i <= num; ++i){
L[i] = (i-1)*block + 1;
R[i] = i*block;
}
R[num] = n;
for (int i = 1; i <= n; ++i){
belong[i] = (i-1)/block+1;
}
for (int i = 1; i <= num; ++i){
for (int j = L[i]; j <= R[i]; ++j){
bit[i].push_back(a[j]);
bit2[i].push_back(a[j]);
fid[a[j] ] = i;
}
sort(bit[i].begin(),bit[i].end());
}
}
int c[maxn];
int sum(int x){
int ans = 0;
while(x){
ans += c[x];
x -= x&-x;
}
return ans;
}
void add(int x,int v){
while(x <= n){
c[x] += v;
x += x&-x;
}
}
int main(){
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
while(~scanf("%d %d",&n, &q)){
for (int i = 1; i <= n; ++i) scanf("%d",a+i);
init();
LL cur = 0;
memset(c,0,sizeof c);
for (int i = 1; i <= n; ++i){
cur += i-1 - sum(a[i]-1);
add(a[i],1);
}
while(q--){
int x;
scanf("%d",&x);
printf("%lld\n",cur);
for (int i = 1; i < fid[x]; ++i){
int t1 = lower_bound(bit[i].begin(),bit[i].end(),x)-bit[i].begin();
cur -= (int)bit[i].size() - t1;
}
for (int i = fid[x]+1; i <= num; ++i){
int t1 = lower_bound(bit[i].begin(),bit[i].end(),x)-bit[i].begin();
cur -= t1;
}
int flag = -1;
for (int i = 0; i < bit2[fid[x] ].size(); ++i){
int v = bit2[fid[x] ][i];
if (v == x){
flag = i;
continue;
}
if (flag == -1){
if (v > x)cur--;
}
else {
if (v < x) cur--;
}
}
bit2[fid[x] ].erase(bit2[fid[x] ].begin() + flag );
bit[fid[x] ].erase(lower_bound(bit[fid[x] ].begin(), bit[fid[x] ].end(),x) );
}
}
return 0;
}
/**
5 4
1
5
3
4
2
5
1
4
2
**/