【bzoj1503】[NOI2004]郁闷的出纳员
2017-03-02 21:29
369 查看
大名鼎鼎的平衡树模板题,话说我当初学平衡树的时候到底去干嘛了,这道题都没做= =。
这道题实际上区间操作蛮水的,因为全部都加减根本不用在树的两侧添加结点,所以直接根节点打标记就好了,每次减少工资的时候查询有没有员工离开了公司。
这个题有一个坑点就是如果工资一开始就少于K就不需要添加进去了,因为这个坑点这道题我调了好久.
1.splay写的不熟练
2.坑点,注意m以下的数直接不要插了
3.注意对size的处理,勤更新
这道题实际上区间操作蛮水的,因为全部都加减根本不用在树的两侧添加结点,所以直接根节点打标记就好了,每次减少工资的时候查询有没有员工离开了公司。
这个题有一个坑点就是如果工资一开始就少于K就不需要添加进去了,因为这个坑点这道题我调了好久.
#include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> //1.splay写的不熟练 //2.坑点,注意m以下的数直接不要插了 //3.注意对size的处理,勤更新 using namespace std; const int N=100010; int n,m; int sz,root; int ch [2],fa ,size ,cnt ,key ,tag ; inline void clear(int x){size[x]=tag[x]=cnt[x]=ch[x][0]=ch[x][1]=fa[x]=key[x]=0;} inline int get(int x){return ch[fa[x]][1]==x;} void pushdown(int x) { if (!x||tag[x]==0)return; if (ch[x][0])key[ch[x][0]]+=tag[x],tag[ch[x][0]]+=tag[x]; if (ch[x][1])key[ch[x][1]]+=tag[x],tag[ch[x][1]]+=tag[x]; tag[x]=0; } inline void updata(int x) { if (!x)return; size[x]=cnt[x]; if (ch[x][0])size[x]+=size[ch[x][0]]; if (ch[x][1])size[x]+=size[ch[x][1]]; } inline void rotate(int x) { pushdown(fa[x]);pushdown(x); int old=fa[x],oldf=fa[old],which=get(x); ch[old][which]=ch[x][which^1],fa[ch[old][which]]=old; ch[x][which^1]=old;fa[old]=x;fa[x]=oldf; if (oldf)ch[oldf][ch[oldf][1]==old]=x; updata(old),updata(x); } inline void splay(int x) { for(int old;(old=fa[x]);rotate(x)) if (fa[old])rotate(get(old)==get(x)?old:x); root=x; } inline void insert(int x) { if (!root){root=++sz;size[sz]=cnt[sz]=1;tag[sz]=fa[sz]=ch[sz][0]=ch[sz][1]=0;key[sz]=x;return;} int now=root,old=0; while(1) { pushdown(now); if (key[now]==x) { cnt[now]++; updata(now); updata(old); splay(now); break; } old=now; now=ch[now][key[now]<x]; if (now==0) { fa[++sz]=old; tag[sz]=ch[sz][0]=ch[sz][1]=0; ch[old][key[old]<x]=sz; cnt[sz]=size[sz]=1; key[sz]=x;updata(old); splay(sz); break; } } } inline int findpos(int x) { int ans=0,now=root; while(1) { pushdown(now); if (x<key[now])now=ch[now][0]; else { ans+=(ch[now][0]?size[ch[now][0]]:0); if (x==key[now]){splay(now);return ans+1;} ans+=cnt[now],now=ch[now][1]; } } } inline int findnth(int x) { if (x>size[root])return -1; int now=root; while(1) { // cout<<"now "<<now<<' '<<key[ch[now][0]]<<' '<<x<<size[ch[now][1]]<<' '<<cnt[now]<<endl; pushdown(now); if (ch[now][1]&&x<=size[ch[now][1]])now=ch[now][1]; else { int temp=(ch[now][1]?size[ch[now][1]]:0)+cnt[now]; if (x<=temp)return key[now]; x-=temp;now=ch[now][0]; } } } inline int pre() { int now=ch[root][0]; while(ch[now][1]) now=ch[now][1]; return now; } inline void del(int x) { findpos(x); if (cnt[root]>1){cnt[root]--;updata(root);return;} if (!ch[root][1]&&!ch[root][0]){clear(root);root=0;return;} if (!ch[root][0]){int oldroot=root;root=ch[root][1];fa[root]=0;clear(oldroot);updata(root);return;} if (!ch[root][1]){int oldroot=root;root=ch[root][0];fa[root]=0;clear(oldroot);updata(root);return;} int leftbig=pre(),oldroot=root; splay(leftbig); ch[root][1]=ch[oldroot][1]; fa[ch[oldroot][1]]=root; clear(oldroot); updata(root); return; } inline void solve(int x) { insert(x); // cout<<"solve root "<<root<<endl; // for (int i=1;i<=sz;++i) // printf("%d %d %d %d %d %d\n",i,key[i],fa[i],ch[i][0],ch[i][1],tag[i]); clear(ch[root][0]); ch[root][0]=0; updata(root); del(x); } int add(int d) { key[root]+=d; tag[root]+=d; pushdown(root); updata(root); } int main() { // freopen("std.in","r",stdin); // freopen("std.out","w",stdout); char s[3]; int qx; int tot=0,k=0; scanf("%d%d",&n,&m); for (int i=1;i<=n;++i) { scanf("%s",s); scanf("%d",&qx); if (s[0]=='I'&&qx>=m)insert(qx),tot++; else if (s[0]=='A')add(qx); else if (s[0]=='S')add(-qx),solve(m),k++; else if (s[0]=='F')printf("%d\n",findnth(qx)); } printf("%d",tot-size[root]); return 0; }
1.splay写的不熟练
2.坑点,注意m以下的数直接不要插了
3.注意对size的处理,勤更新
相关文章推荐
- 【BZOJ1503】[NOI2004]郁闷的出纳员【Splay】
- 平衡二叉树SBT(BZOJ1503[NOI2004]郁闷的出纳员)
- bzoj1503: [NOI2004]郁闷的出纳员
- bzoj1503 [NOI2004]郁闷的出纳员(名次树+懒惰标记)
- bzoj 1503: [NOI2004]郁闷的出纳员
- bzoj 1503 [NOI2004]郁闷的出纳员 平衡树(treap/Splay)
- [BZOJ1503][NOI2004]郁闷的出纳员(平衡树splay)
- [BZOJ1503][NOI2004]郁闷的出纳员 无旋Treap
- Bzoj 1503: [NOI2004]郁闷的出纳员(splay)
- bzoj 1503: [NOI2004]郁闷的出纳员
- 【bzoj 1503】 [NOI2004]郁闷的出纳员
- bzoj1503: [NOI2004]郁闷的出纳员 SBT
- BZOJ 1503 [NOI2004]郁闷的出纳员 (splay)
- [BZOJ1503][NOI2004]郁闷的出纳员
- [NOI2004][BZOJ1503] 郁闷的出纳员
- 【BZOJ】1503: [NOI2004]郁闷的出纳员(Splay)
- bzoj 1503: [NOI2004]郁闷的出纳员 (伸展树)
- [bzoj1503][NOI2004]郁闷的出纳员
- 【BZOJ1503】【NOI2004】郁闷的出纳员
- 【bzoj1503】 [NOI2004]郁闷的出纳员