hdu4441 splay
来源:互联网 发布:华为薪资 知乎 编辑:程序博客网 时间:2024/09/21 09:04
题意:给定一个序列 然后要求维护一个序列 使得这个序列是一个合法的队列结构 然后询问操作是对于+i -i之间的和是多少 删除操作 在原定序列中删除+i 和-i 插入操作插入+i的位置 然后-i的位置是最右边的合法位置
解法:直接上splay就可以了 不过调整了比较久的时间 实际上这三个操作都不是很难
#include<set>#include<cstdio>#include<algorithm>using namespace std;typedef long long ll;#define ls ch[rt][0]#define rs ch[rt][1]#define rrs ch[root][1]#define rls ch[root][0]#define maxn 222222int ch[maxn][2],fa[maxn],num[maxn],pos[maxn],neg[maxn],val[maxn];ll sum[maxn];int root,clc;void up(int rt){sum[rt]=val[rt];num[rt]=1;pos[rt]=(val[rt]>0);neg[rt]=(val[rt]<=0); for(int i=0;i<2;++i){int son=ch[rt][i];if(!son)continue; sum[rt]+=sum[son],num[rt]+=num[son],pos[rt]+=pos[son],neg[rt]+=neg[son];}}inline void rot(int rt){ int f=fa[rt],side=ch[f][1]==rt,ll=ch[rt][!side]; fa[ll]=f,ch[f][side]=ll; fa[rt]=fa[f],ch[fa[f]][ch[fa[f]][1]==f]=rt; fa[f]=rt,ch[rt][!side]=f; up(f),up(rt);}inline void splay(int rt,int aim){ while(fa[rt]!=aim){ int f=fa[rt],ff=fa[f]; if(ff==aim)rot(rt); if((ch[f][1]==rt)==(ch[ff][1]==f))rot(f),rot(rt); else rot(rt),rot(rt); }if(!aim)root=rt;}inline void find(int tot,int sub){ int rt=sub; while(1){ if(tot==num[ls]+1)break; if(num[ls]>=tot)rt=ls; else tot-=num[ls]+1,rt=rs; } splay(rt,fa[sub]);}inline int count(int posi){ int res=0,rt=root; while(rt!=0){ int cnt=(ls==0?(val[rt]<=0):(val[rt]<=0)+neg[ls]); if(posi<cnt)rt=ls; else posi-=cnt,res+=(ls==0?1:1+num[ls]),rt=rs; }return res;}set<int>se;int l[maxn],r[maxn],m,k,_=0;char op[111];inline void init(){ ch[2][0]=ch[2][1]=ch[1][1]=0;ch[1][0]=2; fa[2]=1;fa[1]=0;val[1]=val[2]=0;up(2),up(1); val[0]=num[0]=0; root=1,clc=2;}int main(){while(~scanf("%d",&m)){printf("Case #%d:\n",++_);se.clear();for(int i=1;i<=100000;++i){se.insert(i);l[i]=r[i]=-1;} init();while(m--){scanf("%s %d",op,&k);if(*op=='i'){ int w=(*(se.begin()));se.erase(w); find(k+1,root); find(1,rrs); ch[rrs][0]=++clc;val[clc]=w;ch[clc][0]=ch[clc][1]=0,fa[clc]=rrs;up(clc);splay(clc,0);l[w]=clc; int cnt=count(pos[ch[clc][0]]+1); find(cnt,root); find(1,rrs);ch[rrs][0]=++clc;val[clc]=-w;ch[clc][0]=ch[clc][1]=0;fa[clc]=rrs;up(clc);splay(clc,0);r[w]=clc;}else if(*op=='q'){splay(l[k],0);splay(r[k],root);ll ans=(ch[r[k]][0]==0?0:sum[ch[r[k]][0]]);printf("%I64d\n",ans);}else if(*op=='r'){splay(l[k],0);int cnt=num[rls]; find(cnt,root),find(2,rrs);ch[rrs][0]=0; up(rrs),up(root); splay(r[k],0); cnt=num[rls]; find(cnt,root),find(2,rrs);ch[rrs][0]=0; up(rrs),up(root); se.insert(k);l[k]=r[k]=-1;}}}return 0;}
0 0
- hdu4441 splay
- hdu4441 Queue Sequence(线段树+splay)
- hdu4441 treap
- SPLAY
- splay
- splay
- splay
- Splay
- Splay
- splay
- splay
- splay
- splay
- Splay
- splay
- Splay
- splay
- Splay
- 双向链表的建立,增加,删除操作
- android下图表工具graphview使用简介
- 第一次使用exlipes调试真实手机应注意的问题
- java连接oracle数据库(利用MyEclipse开发工具反向生成 bean与配置文件)
- android 使用shape绘制虚线时,在4.0机型上显示实线
- hdu4441 splay
- 在ASP.NET MVC 模型中 选择最好的方法将多个model(数据模型)传递到视图
- 云计算技术
- freemarker大于,小于 gt,lt 的用法
- HDU 3667 Transportation(最小费用最大流)
- asp模拟post请求
- 一篇厚道的Autolayout及VFL经验分享
- git 版本控制流程
- HDU 3488 Tour(最小费用流:有向环覆盖)