BZOJ - 3295 动态逆序对 (树状数组套treap)
思路和bzoj2141差不多,不过这道题的数据更强一些,线段树套treapT了,树状数组套treap卡过~~
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e5+10,inf=0x3f3f3f3f; 5 int rt[N],n,m,n2,ch[N*30][2],val[N*30],siz[N*30],rd[N*30],tot,a[N],b[N]; 6 ll ans; 7 void pu(int u) {siz[u]=siz[ch[u][0]]+siz[ch[u][1]]+1;} 8 int newnode(int x) {int u=++tot; siz[u]=1,val[u]=x,rd[u]=rand(),ch[u][0]=ch[u][1]=0; return u;} 9 void rot(int& u,int f) { 10 int v=ch[u][f]; 11 ch[u][f]=ch[v][f^1],ch[v][f^1]=u; 12 pu(u),pu(v),u=v; 13 } 14 void ins(int& u,int x) { 15 if(!u) {u=newnode(x); return;} 16 int f=x>val[u]; 17 ins(ch[u][f],x); 18 if(rd[ch[u][f]]>rd[u])rot(u,f); 19 if(u)pu(u); 20 } 21 void del(int& u,int x) { 22 if(val[u]==x) { 23 if(!ch[u][0]||!ch[u][1])u=ch[u][0]|ch[u][1]; 24 else { 25 int f=rd[ch[u][1]]>rd[ch[u][0]]; 26 rot(u,f),del(ch[u][f^1],x); 27 } 28 } else del(ch[u][x>val[u]],x); 29 if(u)pu(u); 30 } 31 int ask(int u,int x) { 32 int ret=0; 33 for(; u; u=ch[u][x>=val[u]])if(x>=val[u])ret+=siz[ch[u][0]]+1; 34 return ret; 35 } 36 void add(int u,int x,int dx) {for(; u<=n; u+=u&-u)dx==1?ins(rt[u],x):del(rt[u],x);} 37 int get1(int u,int x) {int ret=0; for(; u; u-=u&-u)ret+=ask(rt[u],x-1); return ret;} 38 int get2(int u,int x) {int ret=0; for(; u; u-=u&-u)ret+=siz[rt[u]]-ask(rt[u],x); return ret;} 39 40 int main() { 41 srand(time(0)); 42 scanf("%d%d",&n,&m),n2=n; 43 for(int i=1; i<=n; ++i)scanf("%d",&a[i]); 44 for(int i=1; i<=n; ++i)b[a[i]]=i; 45 for(int i=n; i>=1; --i)ans+=get1(n,a[i]),add(i,a[i],1); 46 while(m--) { 47 printf("%lld\n",ans); 48 int x; 49 scanf("%d",&x); 50 int t1=get2(b[x]-1,x),t2=get1(n,x)-get1(b[x],x); 51 ans-=t1+t2; 52 add(b[x],x,-1); 53 n2--; 54 } 55 return 0; 56 }