这题说的是给了一个数组,按照他给的顺序依次删除数,在删除之前输出此时的逆序对个数
我们用Fenwick树 维护这整个数列, C[i]是一个 treap的头, 管理了在树状数组中 能影响他的点,然后我们用名次树去计算 在C[i]下小于等于要删除的那个数的个数就ok了。
#include <iostream> #include <algorithm> #include <string.h> #include <vector> #include <cstdio> #include <stdlib.h> using namespace std; const int maxn=200005; struct Node { Node *ch[2]; int r; int s; int v; int vloc; int cmp(int x)const { if(x==v)return -1; return x<v?0:1; } void maintain() { s=ch[0]->s+ch[1]->s+vloc; } }; Node *null=new Node(); void rotate(Node *&o, int d) { Node *k=o->ch[d^1];o->ch[d^1]=k->ch[d];k->ch[d]=o; o->maintain();k->maintain(); o=k; } void insert(Node *&o,int x) { if(o==null){ o=new Node(); o->ch[0]=o->ch[1]=null; o->v=x; o->r=rand();o->vloc=1;o->s=1; }else{ int d=o->cmp(x); if(d==-1){ o->vloc+=1; }else{ insert(o->ch[d],x);if( o->ch[d]->r > o->r) rotate(o,d^1); } } o->maintain(); } void remove(Node *&o, int x) { int d=o->cmp(x); if(d==-1){ if(o->vloc > 1){ o->vloc-=1; }else if(o->ch[0]==null)o=o->ch[1]; else if(o->ch[1]==null) o=o->ch[0]; else{ int d2 = o->ch[0]->r > o->ch[1]->r ? 1 : 0 ; rotate(o,d2); remove(o->ch[d2],x); } }else remove(o->ch[d],x); if(o!=null) o->maintain(); } int find(Node *o,int x) { int num=0; while(o!=null) { int d=o->cmp(x); if(d==-1){ num += o->ch[0]->s + o->vloc ; break; }else if(d==1){ num+=o->ch[0]->s+o->vloc; o=o->ch[1]; }else{ o=o->ch[0]; } } return num; } Node *C[maxn]; int cc[maxn],A[maxn]; int lowbit(int x) { return (-x)&x; } void init(int n) { for(int i=0; i<=n; i++) C[i]=null,cc[i]=0; } int N,M; void add1(int x, int v) { while(x<=N){ cc[x]+=v; x+=lowbit(x); } } int sum1(int x){ int ans=0; while(x>0){ ans+=cc[x]; x-=lowbit(x); } return ans; } void delet(int x,int v) { while(x<=N) { remove(C[x],v); x+=lowbit(x); } } int summ(int x,int v) { int ans=0; while(x>0) { ans+=find(C[x],v); x-=lowbit(x); } return ans; } int main() { null->s=0; while(scanf("%d%d",&N,&M)==2) { init(N); long long ans=0; for(int i=1; i<=N; i++) { int d; scanf("%d",&d); A[d]=i; ans+=sum1(N)-sum1(d); add1(d,1); int loc=i; while(loc<=N) { insert(C[loc],d); loc+=lowbit(loc); } } for(int i=1; i<=M; i++) { int d; printf("%lld ",ans); scanf("%d",&d); int s1xiaoyu=summ(A[d],d); int ss1=sum1(A[d]); ans-=(ss1-s1xiaoyu); int s2xiaoyu=summ(N,d); ans-=s2xiaoyu-s1xiaoyu; add1(A[d],-1); delet(A[d],d); } } return 0; } /* 5 4 1 5 3 4 2 5 1 4 2 */