bzoj1503
Posted 123456
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1503相关的知识,希望对你有一定的参考价值。
treap改了好长时间,erase写错了。。。
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int inf=1<<29; int n,mn,root,delta,tot,leave; int key[100010],cnt[100010],size[100010],p[100010]; int child[100010][2]; void update(int x) { size[x]=size[child[x][0]]+size[child[x][1]]+cnt[x]; } void rotate(int&x,int t) { int y=child[x][t]; child[x][t]=child[y][1-t]; child[y][1-t]=x; update(x); update(y); x=y; } void insert(int&x,int k) { if(x) { if(key[x]==k) { cnt[x]++; update(x); return; } int t=key[x]<k; insert(child[x][t],k); if(p[x]<p[child[x][t]]) rotate(x,t); update(x); } else { tot++; x=tot; p[x]=rand(); key[x]=k; cnt[x]=1; update(x); } } void erase(int&x,int k) { if(key[x]==k) { if(!child[x][0]&&!child[x][1]) { x=0; return; } int t=p[child[x][1]]>p[child[x][0]]; rotate(x,t); erase(child[x][t^1],k); } else erase(child[x][key[x]<k],k); update(x); } void _erase(int x) { if(x==0) return; if(key[x]+delta<mn) { leave+=cnt[x]; if(key[child[x][0]]+delta<mn) { leave+=size[child[x][0]]; child[x][0]=0; update(x); } _erase(child[x][1]); erase(root,key[x]); } _erase(child[x][0]); } int find(int x,int k) { if(k<=size[child[x][1]]) return find(child[x][1],k); k-=size[child[x][1]]+cnt[x]; if(k<=0) return key[x]; return find(child[x][0],k); } int main() { p[0]=-inf; scanf("%d%d",&n,&mn); while(n--) { char s[10]; int k; scanf("%s%d",s,&k); if(s[0]==‘I‘) { if(k>=mn) insert(root,k-delta); } if(s[0]==‘A‘) { delta+=k; } if(s[0]==‘S‘) { delta-=k; _erase(root); } if(s[0]==‘F‘) { if(k>size[root]) printf("-1\n"); else printf("%d\n",find(root,k)+delta); } } printf("%d\n",leave); return 0; }
以上是关于bzoj1503的主要内容,如果未能解决你的问题,请参考以下文章