时间、位置、数字为三个属性。
排序时间,CDQ位置,树状数组处理数字即可。
#include#include #include #include using namespace std;#define F(i,j,k) for (int i=j;i<=k;++i)#define D(i,j,k) for (int i=j;i>=k;--i)#define ll long long#define maxn 100005int a[maxn],q[maxn],n,m,pos[maxn],del[maxn];struct Event{ int t;//时间 int x;//加入的数 int y;//加入的位置 }b[maxn];struct Bit_Tree{ int x[maxn]; void add(int i,int f) { for (;i b.y;} ll ans[maxn]; void CDQ(int l,int r,int flag){ if (l==r) return ; int mid=l+r>>1; CDQ(l,mid,flag); CDQ(mid+1,r,flag); int pl=l; if (flag) F(i,mid+1,r) { while (b[pl].y <=mid) BT.add(b[pl++].x,1); int tmp=BT.gs(n)-BT.gs(b[i].x-1); ans[b[i].t]+=tmp; } else F(i,mid+1,r) { while (b[pl].y>b[i].y&&pl<=mid) BT.add(b[pl++].x,1); int tmp=BT.gs(b[i].x-1); ans[b[i].t]+=tmp; } F(i,l,pl-1) BT.add(b[i].x,-1); sort(b+l,b+r+1,flag?cmp2:cmp3);} int main(){ scanf("%d%d",&n,&m); F(i,1,n) scanf("%d",&a[i]),pos[a[i]]=i; F(i,1,m) { scanf("%d",&q[i]); del[q[i]]=1; b[i].t=n-i+1; b[i].x=q[i]; b[i].y=pos[q[i]]; } int now=m; F(i,1,n) if (!del[i]) { b[++now].t=n-now+1; b[now].x=i; b[now].y=pos[i]; } sort(b+1,b+n+1,cmp1); CDQ(1,n,1); sort(b+1,b+n+1,cmp1); CDQ(1,n,0); F(i,2,n) ans[i]+=ans[i-1]; D(i,n,n-m+1) printf("%lld\n",ans[i]);}