传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3295
用树状数组套平衡树统计逆序对,每加入一个数就统计在它前面比他大+在他后面比他大,可以离线,逆序加入数字,可以更快一点,
PS:线段树常数真心不能看……
Code:
#include<cstdio> #include<climits> #include<iostream> #include<algorithm> #define lson i<<1,l,mid #define rson i<<1|1,mid+1,r #define L i<<1 #define R i<<1|1 using namespace std; const int maxn=1e5+10; const int maxm=50010; int n,m; int a[maxn],b[maxm]; bool hash[maxn]; int rnd(){ static int KEY=12345678; return KEY+=KEY<<2|1; } int getint(){ int res=0,ok=0;char ch; while(1){ ch=getchar(); if(ch<='9'&&ch>='0'){ res*=10;res+=ch-'0';ok=1; }else if(ok)break; }return res; } struct Treap{ struct node{ int val,key; int size; node *c[2]; node(int _val,node *C){ val=_val;key=rnd(); c[0]=c[1]=C;size=1; } void rz(){ size=c[0]->size+c[1]->size+1; } }; node *root,*Null; Treap(){ Null=new node(0,0); Null->size=0;Null->c[0]=Null->c[1]=Null; Null->key=INT_MAX;root=Null; } void rot(node *&t,bool d){ node *p=t->c[d]; t->c[d]=p->c[!d]; p->c[!d]=t; t->rz();p->rz(); t=p; } void _insert(node *&t,int x){ if(t==Null){ t=new node(x,Null); return ; } bool d=x>t->val; _insert(t->c[d],x); if(t->c[d]->key<t->key) rot(t,d); else t->rz(); } void _del(node *&t,int x){ if(t->val==x){ bool d=t->c[0]->key<t->c[1]->key; if(t->c[d]==Null){ delete t; t=Null; return; } rot(t,d); _del(t->c[!d],x); }else{ bool d=x>t->val; _del(t->c[d],x); } t->rz(); } int _rank(node *&t,int x){ if(t==Null)return 0; int r=t->c[0]->size; if(x==t->val)return r; if(x<t->val)return _rank(t->c[0],x); else return r+1+_rank(t->c[1],x); } void _deb(node *&t){ printf("val:%d size:%d\n",t->val,t->size); if(t->c[0]!=Null){ printf("L: ");_deb(t->c[0]); } if(t->c[1]!=Null){ printf("R: ");_deb(t->c[1]); } } void deb(){_deb(root);} void insert(int x){_insert(root,x);} void del(int x){_del(root,x);} int rank(int x){return _rank(root,x);} int size(){return root->size;} }; Treap d[maxn]; int lowbit(int x){ return x&(-x); } void updata(int x,int val){ while(x<=n){ d[x].insert(val); x+=lowbit(x); } } int get(int x,int val){ if(x==0)return 0; int ans=0; while(x){ ans+=d[x].rank(val); x-=lowbit(x); } return ans; } int size(int x){ if(x==0)return 0; int ans=0; while(x){ ans+=d[x].size(); x-=lowbit(x); } return ans; } long long anss[maxm]; int p[maxn]; long long ans=0; int main(){ // freopen("1.txt","r",stdin); // freopen("3.txt","w",stdout); n=getint();m=getint(); for(int i=1;i<=n;i++)a[i]=getint(),p[a[i]]=i; for(int i=1;i<=m;i++)b[i]=getint(),hash[b[i]]=1; for(int i=1;i<=n;i++){ if(!hash[a[i]]){ updata(i,a[i]); ans+=get(n,a[i])-get(i,a[i]); ans+=size(i-1)-get(i-1,a[i]); //T.Change(1,1,n,i,a[i]); //ans+=T.Rank(1,1,n,i+1,n,a[i]); //ans+=T.size(1,1,n,1,i-1)-T.Rank(1,1,n,1,i-1,a[i]); //T.deb(); } } for(int i=m;i>=1;i--){ updata(p[b[i]],b[i]); ans+=get(n,b[i])-get(p[b[i]],b[i]); ans+=size(p[b[i]]-1)-get(p[b[i]]-1,b[i]); //ans+=T.Rank(1,1,n,p[b[i]]+1,n,b[i]); //ans+=T.size(1,1,n,1,p[b[i]]-1)-T.Rank(1,1,n,1,p[b[i]]-1,b[i]); //T.deb();cout<<endl; anss[i]=ans; } for(int i=1;i<=m;i++) printf("%lld\n",anss[i]); return 0; }