BZOJ 3295
http://www.lydsy.com/JudgeOnline/problem.php?id=3295
时光倒流,把删除操作变成添加操作
那么就有三个维度(大小,位置,时间)
逆序对满足
ai<aj && bi<bj && ci>cj
ai<aj && bi>bj && ci<cj
那么,这不就是三维偏序嘛
时间维排序处理
位置维cdq分治,归并排序处理
大小维树状数组维护
#include<cstdio> #include<algorithm> #define FOR(i,s,t) for(register int i=s;i<=t;++i) #define ROF(i,s,t) for(register int i=s;i>=t;--i) using namespace std; typedef long long ll; int n,m,tot; const int N=100011; struct node{ int x,y,z; }q[N],t[N]; int pos[N],a[N],v; ll ans[N]; int bo[N]; namespace BIT{ int tr[N]; inline void add(int pos){for(;pos<=n;++tr[pos],pos+=pos&-pos);} inline int query(int pos){int ret=0;for(;pos;pos-=pos&-pos)ret+=tr[pos];return ret;} inline void del(int pos){for(;pos<=n;pos+=pos&-pos)if(tr[pos])tr[pos]=0;else break; } }; using namespace BIT; inline void cdq(int l,int r){ if(l==r)return; int mid=(l+r)>>1; cdq(l,mid);cdq(mid+1,r); int idx1=l,idx2=mid+1; FOR(i,l,r)t[i]=q[(idx2>r||(idx1<=mid&&q[idx1].y<q[idx2].y))?idx1++:idx2++]; FOR(i,l,r)q[i]=t[i]; int all=0; FOR(i,l,r) if(q[i].x<=mid)add(q[i].z),++all; else ans[q[i].x]+=1ll*(all-query(q[i].z)); FOR(i,l,r)del(q[i].z); ROF(i,r,l) if(q[i].x<=mid)add(q[i].z); else ans[q[i].x]+=1ll*query(q[i].z); ROF(i,r,l)del(q[i].z); } int main(){ scanf("%d%d",&n,&m); FOR(i,1,n)scanf("%d",&v),pos[v]=i; FOR(i,1,m)scanf("%d",a+i),bo[a[i]]=1; FOR(i,1,n)if(!bo[i])q[++tot]=(node){tot,pos[i],i}; ROF(i,m,1)q[++tot]=(node){tot,pos[a[i]],a[i]}; cdq(1,n); FOR(i,1,n)ans[i]+=1ll*ans[i-1]; ROF(i,n,n-m+1)printf("%lld\n",ans[i]); return 0; }