CODEVS 1286(伸展树)
来源:互联网 发布:沃尔玛数据流程图 编辑:程序博客网 时间:2024/06/12 06:34
题目链接:http://codevs.cn/problem/1286/
题解:伸展树,一定要记住,任何被操作过的节点都要旋转到根,插入节点后要把该节点旋转到根,查找节点后也要把它旋转到根,删除节点也要先旋转到根再删除,如果不旋转到根,妥妥的超时。
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define N 100010int c[N][2],fa[N],v[N],num[N],sum[N];int n,m,cnt,rt;void pushup(int k){ sum[k]=sum[c[k][0]]+sum[c[k][1]]+num[k];}void rotate(int x,int &k){ int y=fa[x],z=fa[y],l,r; if(c[y][0]==x) l=0;else l=1;r=l^1; if(y==k) k=x; else if(c[z][0]==y) c[z][0]=x;else c[z][1]=x; fa[x]=z;fa[y]=x;fa[c[x][r]]=y; c[y][l]=c[x][r];c[x][r]=y; pushup(y);pushup(x);}void splay(int x,int &k){ while(x!=k) { int y=fa[x],z=fa[y]; if(y!=k) { if(c[z][0]==y^c[y][0]==x) rotate(x,k); else rotate(y,k); } else rotate(x,k); }}void ins(int val,int &k,int last){ if(k==0) { k=++cnt;v[k]=val;fa[k]=last;num[k]=sum[k]=1; splay(k,rt); } else if(v[k]==val) { ++num[k];++sum[k];splay(k,rt); } else if(val<=v[k]) ++sum[k],ins(val,c[k][0],k); else ++sum[k],ins(val,c[k][1],k);}int find(int k,int val){ if(k==0) return 0; else if(v[k]+val>=m) return find(c[k][0],val); else { int t=find(c[k][1],val); if(t==0) t=k; return t; }}void del(int val){ int x=find(rt,val); if(x==0) return; splay(x,rt); rt=c[x][1];fa[rt]=0;}int find_k(int k,int rank){ int l=c[k][0],r=c[k][1]; if(rank<=sum[r]) return find_k(r,rank); else if(sum[r]+num[k]<rank) return find_k(l,rank-sum[r]-num[k]); else { splay(k,rt);return v[k]; }}int read(){ int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9')ch=getchar(); while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x;}int main(){ n=read();m=read(); int z=0,k,tot=0; char ch; for(int i=1;i<=n;++i) { for(ch=getchar();ch<'A'||'Z'<ch;ch=getchar()); k=read(); switch(ch) { case 'I':if(k>=m) ++tot,ins(k-z,rt,0);break; case 'A':z+=k;break; case 'S':z-=k;del(z);break; case 'F': if(k>sum[rt]) printf("-1\n"); else printf("%d\n",find_k(rt,k)+z); break; } } printf("%d\n",tot-sum[rt]); return 0;}
阅读全文
0 0
- CODEVS 1286(伸展树)
- CODEVS 1343(伸展树)
- CODEVS 1743(伸展树区间翻转)
- 伸展树(splay)
- 伸展树(转载)
- 伸展树(Splay)
- 伸展树:双层伸展
- 伸展树( splay tree)
- 伸展树hdu4453(good)
- Splay Tree(伸展树)
- 伸展树(splay tree)
- 伸展树(Splay Tree)
- 伸展树(Splay tree)
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- 伸展树
- A
- 动态规划经典题讲解
- CAD编辑指南1:CAD图纸的批量打印和批量修改文字
- POJ
- 编程珠玑课后题答案-3.5
- CODEVS 1286(伸展树)
- linux文本管理工具命令详解
- PDF编辑指南1:PDF水印的删除和添加
- 【线段树区间单点更新加约束条件】Range Minimum Queries CodeChef
- android如何打开系统wifi、蓝牙等设置界面
- 变量
- php中mysql预处理语句
- UVA
- 1014. 福尔摩斯的约会