1. 程式人生 > >bzoj3295: [Cqoi2011]動態逆序對

bzoj3295: [Cqoi2011]動態逆序對

lowbit 包含 point gpo for oid sort register open

3295: [Cqoi2011]動態逆序對

Description

? 對於序列A,它的逆序對數定義為滿足i

Input

輸入第一行包含兩個整數n和m,即初始元素的個數和刪除的元素個數。

以下n行每行包含一個1到n之間的正整數,即初始排列。

以下m行每行一個正整數,依次為每次刪除的元素。

Output

輸出包含m行,依次為刪除每個元素之前,逆序對的個數。

數據範圍

$N \leqslant 100000 , M \leqslant50000 $

這道題將插入時間轉化為一維,就是個三維偏序,直接cdq即可。

註意輸入的是元素大小,而不是元素個數。

#include<bits/stdc++.h>
using
namespace std; #define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i) #define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i) typedef long long ll; inline int read(){ int x; char c; int f=1; while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘)); if
(c==‘-‘) c=getchar(),f=-1; x=c^‘0‘; while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1)+(x<<3)+(c^‘0‘); return x*f; } inline ll readll(){ ll x; char c; ll f=1; while((c=getchar())!=‘-‘ && (c<‘0‘ || c>‘9‘)); if(c==‘-‘) c=getchar(),f=-1; x=c^‘0‘
; while((c=getchar())>=‘0‘ && c<=‘9‘) x=(x<<1ll)+(x<<3ll)+(c^‘0‘); return x*f; } inline bool chkmax(int &x,int y){return (y>x)?(x=y,1):0;} inline bool chkmin(int &x,int y){return (y<x)?(x=y,1):0;} const int maxn=1e5+10; struct point{ int x,y,z,sum; }a[maxn]; bool cmpx(const point A,const point B){ if(A.x!=B.x) return A.x<B.x; if(A.y!=B.y) return A.y<B.y; return A.z<B.z; } bool cmpy(const point A,const point B){ if(A.y!=B.y) return A.y<B.y; return A.z<B.z; } int n; ll ans[maxn]; struct szsz{ int c[maxn]; int lowbit(int x){ return x&(-x); } int sum(int x){ int res=0; while(x){ res+=c[x]; x-=lowbit(x); } return res; } void add(int x,int y){ while(x<=n){ c[x]+=y; x+=lowbit(x); } } }bit; void cdq(int L,int R){ if(L>=R) return; int Mid=(L+R)>>1; cdq(L,Mid),cdq(Mid+1,R); sort(a+L,a+Mid+1,cmpy),sort(a+Mid+1,a+R+1,cmpy); int j=L; for(int i=Mid+1;i<=R;++i){ while(j<=Mid && a[j].y<=a[i].y) bit.add(a[j].z,1),++j; a[i].sum+=bit.sum(n)-bit.sum(a[i].z); } REP(i,L,j-1) bit.add(a[i].z,-1); j=Mid; for(int i=R;i>Mid;--i){ while(j>=L && a[j].y>=a[i].y) bit.add(a[j].z,1),--j; a[i].sum+=bit.sum(a[i].z); } DREP(i,Mid,j+1) bit.add(a[i].z,-1); } int mp[maxn]; int main(){ #ifndef ONLINE_JUDGE freopen("cdq.in","r",stdin); freopen("cdq.out","w",stdout); #endif n=read();int m=read(); REP(i,1,n) a[i].x=0,a[i].y=i,a[i].z=read(),mp[a[i].z]=i; int num=n; REP(i,1,m){ int x=read();x=mp[x]; a[x].x=num--; } REP(i,1,m) if(a[i].x==0) a[i].x=num--; sort(a+1,a+n+1,cmpx); cdq(1,n); REP(i,1,n) ans[a[i].x]+=a[i].sum; REP(i,1,n) ans[i]+=ans[i-1]; DREP(i,n,n-m+1) printf("%lld\n",ans[i]); return 0; }

bzoj3295: [Cqoi2011]動態逆序對