CDQ Divide and conquer.
Code
#include <cstdio>#include<algorithm>#defineN 200010#defineLB (x) (x&-x)using namespacestd;intN,b[n],a[n],id[n],ans[n],i,m,l[n],r[n],c[n];Long LongAns;structg{intV,typ;} V[n];BOOLCMP (g A,g b) {returna.v<B.V;}voidccintXintW) { while(x<=N) {c[x]+=W; X+=lb (x); }}intSumintx) { intans=0; while(x) {ans+=C[x]; X-=lb (x); } returnans;}voidSolveintLintR) { intm,i,tot=0, cnt=0; if(L>=R)return; M= (l+r) >>1; for(i=l;i<=m;i++) {v[++tot].typ=0; V[TOT].V=B[i]; } for(i=m+1; i<=r;i++) {v[++tot].typ=i; V[TOT].V=B[i]; } sort (v+1, v+1+tot,cmp); for(i=tot;i>=1; i--) if(V[i].typ) Ans[v[i].typ]+=sum (ID[V[I].V]); Elsecc (ID[V[I].V],1); for(i=1; i<=tot;i++) if(v[i].typ==0) cc (ID[V[I].V],-1); for(i=1; i<=tot;i++) if(V[i].typ) Ans[v[i].typ]+=cnt-sum (ID[V[I].V]); Else{cnt++; CC (ID[V[I].V],1); } for(i=1; i<=tot;i++) if(v[i].typ==0) cc (ID[V[I].V],-1); Solve (l,m); Solve (M+1, R);}intMain () {scanf ("%d%d",&n,&m); for(i=1; i<=n;i++) {scanf ("%d",&A[i]); Id[a[i]]=i; } for(i=1; i<=n;i++) {L[i]=sum (N)-sum (a[i]); CC (A[i],1); } for(i=1; i<=n;i++) C[i]=0; for(i=n;i>=1; i--) {R[i]=sum (a[i]); CC (A[i],1); } for(i=1; i<=n;i++) C[i]=0; for(i=1; i<=n;i++) Ans=ans+L[i]; for(i=1; i<=m;i++) scanf ("%d",&B[i]); Solve (1, M); for(i=1; i<=m;i++) {printf ("%lld\n", Ans); Ans=ans-l[id[b[i]]]-r[id[b[i]]]+Ans[i]; } }
bzoj3295 [Cqoi2011] Dynamic reverse order