题解:
将前n个数看作插入,后m个数仍看作删除。
然后就是cdq分治。
代码:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 150050 #define ll long long inline int rd() { int f=1,c=0;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){c=10*c+ch-'0';ch=getchar();} return f*c; } int n,m; struct node { int a,b,c,d; }p[N],tmp[N]; int pos[N]; ll ans[N]; int f[N]; void up(int x,int d) { if(!x)return ; while(x<=100000)f[x]+=d,x+=(x&(-x)); } int down(int x) { if(!x)return 0; int ret = 0; while(x)ret+=f[x],x-=(x&(-x)); return ret; } void Sort(int l,int r) { int mid = (l+r)>>1; int i=l,j=mid+1,k=l; while(i<=mid&&j<=r) { while(p[i].a<=p[j].a&&i<=mid) { tmp[k]=p[i]; i++,k++; } while(p[i].a>p[j].a&&j<=r) { tmp[k]=p[j]; j++,k++; } } while(i<=mid) { tmp[k]=p[i]; i++,k++; } while(j<=r) { tmp[k]=p[j]; j++,k++; } for(i=l;i<=r;i++) p[i]=tmp[i]; } void cdq(int l,int r) { if(l==r)return ; int mid = (l+r)>>1; cdq(l,mid),cdq(mid+1,r); Sort(l,mid),Sort(mid+1,r); int i,j; j = l; for(i=mid+1;i<=r;i++) { while(j<=mid&&p[i].a>=p[j].a)up(p[j].b,p[j].d),j++; ans[p[i].c]+=p[i].d*(down(n)-down(p[i].b)); } for(j=j-1;j>=l;j--)up(p[j].b,-p[j].d); j = mid; for(i=r;i>mid;i--) { while(j>=l&&p[i].a<=p[j].a)up(p[j].b,p[j].d),j--; ans[p[i].c]+=p[i].d*down(p[i].b-1); } for(j=j+1;j<=mid;j++)up(p[j].b,-p[j].d); } int main() { n=rd(),m=rd(); for(int x,i=1;i<=n;i++) { x=rd(); p[i].a=i,p[i].b=x,p[i].c=0,p[i].d=1; pos[x]=i; } for(int x,j,i=1;i<=m;i++) { x=rd();j=i+n; p[j].a=pos[x],p[j].b=x,p[j].c=i,p[j].d=-1; } cdq(1,n+m); for(int i=1;i<=m;i++)ans[i]+=ans[i-1]; for(int i=0;i<m;i++)printf("%lld ",ans[i]); return 0; } //pos val tim wgt