bzoj3192 [JLOI2013]删除物品
用数组表示两个栈,将两个栈的栈顶并在一起,用树状数组维护一下操作即可。
代码
1 #include<cstdio> 2 #include<algorithm> 3 #include<map> 4 #define lb(x) (x&-x) 5 using namespace std; 6 const int N = 501010; 7 int n,m,i,id[N],a[N],b[N],c[N],top,tot; 8 long long ans; 9 map<int,int> ma; 10 void cc(int x,int w) 11 { 12 while (x<=n+m) 13 { 14 c[x]+=w; 15 x+=lb(x); 16 } 17 } 18 int sum(int x) 19 { 20 int ans=0; 21 while (x) 22 { 23 ans+=c[x]; 24 x-=lb(x); 25 } 26 return ans; 27 } 28 int main() 29 { 30 scanf("%d%d",&n,&m); 31 for (i=1;i<=n;i++) 32 scanf("%d",&a[i]),b[i]=a[i]; 33 for (i=n+1;i<=n+m;i++) 34 scanf("%d",&a[i]),b[i]=a[i]; 35 sort(b+1,b+1+m+n); 36 for (i=1;i<=n+m;i++) 37 if (ma[b[i]]==0) ma[b[i]]=++tot; 38 for (i=1;i<=n+m;i++) a[i]=ma[a[i]]; 39 for (i=1;i<=n;i++) 40 id[a[i]]=n-i+1; 41 for (i=1;i<=m;i++) 42 id[a[n+i]]=n+i; 43 44 for (i=1;i<=n+m;i++) cc(i,1); 45 46 top=n; 47 for (i=n+m;i>=1;i--) 48 { 49 if (id[i]<=top) 50 { 51 ans+=sum(top)-sum(id[i]); 52 top=id[i]; 53 } 54 else 55 { 56 ans+=sum(id[i]-1)-sum(top); 57 top=id[i]; 58 } 59 cc(id[i],-1); 60 } 61 printf("%lld\n",ans); 62 }