这个东西,关于某个数的逆序对数为在他之前比他大的在他之后比他小的数的数目的和,所以删除之前先把这个减去就好了
人傻自带超大常数,中间由于内存池开小了所以运行错误。
#include<cstdio> #include<iostream> #include<cstring> #define MAXN 100010 using namespace std; typedef long long LL; typedef double D; const D a=0.756; LL ans; struct ScapeGoat_Tree { ScapeGoat_Tree *ch[2]; int key,size,cover,ex; bool bad() { return cover*a+5<ch[0]->cover||cover*a+5<ch[1]->cover; } void pushup() { size=ch[0]->size+ch[1]->size+ex; cover=ch[0]->cover+ch[1]->cover+1; } }*null,*stack[(MAXN<<5)+5],pool[(MAXN<<5)+5],*lst[(MAXN<<4)+5]; int top,len; inline void Init() { null=pool; null->ch[1]=null->ch[0]=null; null->key=null->size=null->cover=null->ex=0; for(int i=1;i<(MAXN<<5);i++)stack[++top]=pool+i; } inline ScapeGoat_Tree *New(int key) { ScapeGoat_Tree *p=stack[top--]; p->ch[1]=p->ch[0]=null; p->key=key; p->size=p->ex=p->cover=1; return p; } struct Tree { Tree *ch[2]; int mid,l,r; ScapeGoat_Tree *root; Tree(){ch[1]=ch[0]=NULL;mid=l=r=0;root=null;} void* operator new(size_t size); }*root,*C,*mempool; void* Tree :: operator new(size_t size) { if(C==mempool) { C=new Tree[(1<<15)+5]; mempool=C+(1<<15)+5; } C->root=null; return C++; } void travel(ScapeGoat_Tree *p) { if(p==null)return; travel(p->ch[0]); if(p->ex)lst[++len]=p; else stack[++top]=p; travel(p->ch[1]); } ScapeGoat_Tree *divide(int l,int r) { if(l>r)return null; int mid=(l+r)>>1; lst[mid]->ch[0]=divide(l,mid-1); lst[mid]->ch[1]=divide(mid+1,r); lst[mid]->pushup(); return lst[mid]; } inline void rebuild(ScapeGoat_Tree *&p) { len=0; travel(p); p=divide(1,len); } ScapeGoat_Tree **insert(ScapeGoat_Tree *&p,int key) { if(p==null ) { p=New(key); return &null; } p->size++; p->cover++; ScapeGoat_Tree **ret=insert(p->ch[p->key<=key],key); if(p->bad())ret=&p; return ret; } inline void Insert(ScapeGoat_Tree *&Root,int key) { ScapeGoat_Tree **p=insert(Root,key); if(*p!=null )rebuild(*p); } inline int Rank_Max(ScapeGoat_Tree *Root,int key) { ScapeGoat_Tree *now=Root; int ret=0; while(now!=null ) if(now->key<=key) now=now->ch[1]; else ret+=now->ch[1]->size+now->ex,now=now->ch[0]; return ret; } inline int Rank_Min(ScapeGoat_Tree *Root,int key) { ScapeGoat_Tree *now=Root; int ret=0; while(now!=null ) if(now->key>=key) now=now->ch[0]; else ret+=now->ch[0]->size+now->ex,now=now->ch[1]; return ret; } void del(ScapeGoat_Tree *p,int k) { p->size--; if(p->ex&&p->ch[0]->size+1==k) { p->ex=0; return; } if(p->ch[0]->size>=k) del(p->ch[0],k); else del(p->ch[1],k-p->ch[0]->size-p->ex); } inline void Del(ScapeGoat_Tree *&Root,int key) { del(Root,Rank_Min(Root,key)+1); if(Root->size<Root->cover*a)rebuild(Root); } int n,m,pos[MAXN]; void build(Tree *p) { p->mid=(p->l+p->r)>>1; if(p->l==p->r)return; p->ch[0]=new Tree; p->ch[0]->l=p->l; p->ch[0]->r=p->mid; p->ch[1]=new Tree; p->ch[1]->l=p->mid+1; p->ch[1]->r=p->r; build(p->ch[0]); build(p->ch[1]); } void Ins(Tree *p,int key,int aim) { Insert(p->root,key); if(p->l==p->r)return; Ins(p->ch[p->mid<aim],key,aim); } int query_Max(int l,int r,int key,Tree *p) { if(l<=p->l&&p->r<=r) return Rank_Max(p->root,key); int tmp=0; if(l<=p->mid)tmp+=query_Max(l,r,key,p->ch[0]); if(p->mid<r)tmp+=query_Max(l,r,key,p->ch[1]); return tmp; } int query_Min(int l,int r,int key,Tree *p) { if(l<=p->l&&p->r<=r) return Rank_Min(p->root,key); int tmp=0; if(l<=p->mid)tmp+=query_Min(l,r,key,p->ch[0]); if(p->mid<r)tmp+=query_Min(l,r,key,p->ch[1]); return tmp; } void Delete(Tree *p,int key,int aim) { Del(p->root,key); if(p->l==p->r)return; Delete(p->ch[p->mid<aim],key,aim); } int main() { //freopen("inverse.in","r",stdin); //freopen("inverse.out","w",stdout); Init(); scanf("%d%d",&n,&m); root=new Tree; root->l=1; root->r=n; build(root); for(int i=1;i<=n;i++) { int x; scanf("%d",&x); pos[x]=i; Ins(root,x,i); if(i!=1)ans+=query_Max(1,i-1,x,root); } for(int i=1;i<=m;i++) { printf("%lld ",ans); int x; scanf("%d",&x); if(pos[x]!=1) ans-=query_Max(1,pos[x]-1,x,root); if(pos[x]!=n) ans-=query_Min(pos[x]+1,n,x,root); Delete(root,x,pos[x]); } return 0; }