先归并排序处理出初始逆序对数
然后树状数组套主席树进行修改和查询
删除数x时(设x位置为pos[x]),从原逆序对数中减去与该数有关的逆序对数,即([1,pos[x]-1]中大于x的数的个数)+([pos[x]+1,n]中小于x的数的个数),并从树状数组中将x删除
另外注意存答案要用long long,否则会爆
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=100010;
typedef long long LL;
int n,m,a[maxn],pos[maxn];
LL ans;
inline int read(){
int ret=0,sign=1;
char ch=getchar();
while(ch<'0'||ch>'9') {if(ch=='-') sign=-1; ch=getchar();}
while(ch>='0'&&ch<='9') {ret=ret*10+ch-'0'; ch=getchar();}
return ret*sign;
}
struct node{
int sum,son[2];
}T[maxn*300];
int root[maxn],cnt;
int tmp1[maxn],tmp2[maxn];
LL merge(int l,int r){
if(l==r) return 0;
int mid=(l+r)>>1;
LL ret=merge(l,mid)+merge(mid+1,r);
int i=l,j=mid+1,k=l;
for(;j<=r;j++){
while(i<=mid&&tmp1[i]<=tmp1[j]) tmp2[k++]=tmp1[i++];
ret+=mid-i+1,tmp2[k++]=tmp1[j];
}
for(;i<=mid;i++)
tmp2[k++]=tmp1[i];
for(int p=l;p<=r;p++)
tmp1[p]=tmp2[p];
return ret;
}
void ins(int &u,int l,int r,int x,int op){
if(!u) u=++cnt;
T[u].sum+=op;
int mid=(l+r)>>1;
if(l==r) return;
if(x<=mid) ins(T[u].son[0],l,mid,x,op);
else ins(T[u].son[1],mid+1,r,x,op);
}
inline int lbt(int x){return x&(-x);}
inline void add(int u,int op){for(int i=u;i<=n;i+=lbt(i)) ins(root[i],1,n,a[u],op);}
int tmpU[2][20],tmpN[2];
LL query(int l,int r,int x,int op){
if(l>r) return 0;
tmpN[0]=tmpN[1]=0;
for(int i=l-1;i;i-=lbt(i)) tmpU[0][++tmpN[0]]=root[i];
for(int i=r;i;i-=lbt(i)) tmpU[1][++tmpN[1]]=root[i];
int vl=1,vr=n;
LL ret=0;
if(op==1) while(1){
if(vr==x) break;
int mid=(vl+vr)>>1,rsum=0;
for(int i=1;i<=tmpN[0];i++) rsum-=T[T[tmpU[0][i]].son[1]].sum;
for(int i=1;i<=tmpN[1];i++) rsum+=T[T[tmpU[1][i]].son[1]].sum;
int rela=x>mid;
if(!rela) ret+=rsum,vr=mid;
else vl=mid+1;
for(int i=1;i<=tmpN[0];i++) tmpU[0][i]=T[tmpU[0][i]].son[rela];
for(int i=1;i<=tmpN[1];i++) tmpU[1][i]=T[tmpU[1][i]].son[rela];
}
else while(1){
if(vl==x) break;
int mid=(vl+vr)>>1,lsum=0;
for(int i=1;i<=tmpN[0];i++) lsum-=T[T[tmpU[0][i]].son[0]].sum;
for(int i=1;i<=tmpN[1];i++) lsum+=T[T[tmpU[1][i]].son[0]].sum;
int rela=x>mid;
if(rela) ret+=lsum,vl=mid+1;
else vr=mid;
for(int i=1;i<=tmpN[0];i++) tmpU[0][i]=T[tmpU[0][i]].son[rela];
for(int i=1;i<=tmpN[1];i++) tmpU[1][i]=T[tmpU[1][i]].son[rela];
}
return ret;
}
int main(){
n=read(),m=read();
for(int i=1;i<=n;i++)
tmp1[i]=a[i]=read(),pos[a[i]]=i;
ans=merge(1,n);
for(int i=1;i<=n;i++)
add(i,1);
for(int i=1;i<=m;i++){
int x=read();
printf("%lld\n",ans);
ans-=query(1,pos[x]-1,x,1)+query(pos[x]+1,n,x,-1);
add(pos[x],-1);
}
return 0;
}