POJ3580 SuperMemo(区间树)
来源:互联网 发布:孟加拉地区代码数据库 编辑:程序博客网 时间:2024/04/20 11:24
唯一一个要说的就是REVOLVE操作。别的在笔记上有。
可以发现REVOLVE就是把一段区间砍下来然后接在一个点后面。
那么先把这个区间砍下来(rotateto(l-1,0)rotateto(r+1,root)),然后pushup,然后找到那个点(rotateto(x,0)rotateto(x+1,root)),然后插入回去。最后pushup。
#include<iostream>#include<cstdio>#include<cstring>using namespace std;int n,m,rt,cnt,x,y,z,a[200010],sz[200010],ch[200010][2],fa[200010],v[200010],delta[200010],rev[200010],minum[200010];char c,op[7];inline void GET(int &n){ int f=1;n=0; do{c=getchar();if(c=='-')f=-1;}while(c>'9'||c<'0'); while(c<='9'&&c>='0'){n=n*10+c-'0';c=getchar();} n*=f;}inline void pushdown(int x){ if(delta[x]) { delta[ch[x][0]]+=delta[x]; minum[ch[x][0]]+=delta[x]; v[ch[x][0]]+=delta[x]; delta[ch[x][1]]+=delta[x]; minum[ch[x][1]]+=delta[x]; v[ch[x][1]]+=delta[x]; delta[x]=0; } if(rev[x]) { rev[ch[x][0]]^=1; rev[ch[x][1]]^=1; swap(ch[x][0],ch[x][1]); rev[x]=0; }}inline void pushup(int x){ sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+1; minum[x]=v[x]; if(ch[x][0])minum[x]=min(minum[x],minum[ch[x][0]]); if(ch[x][1])minum[x]=min(minum[x],minum[ch[x][1]]);}inline void rotate(int x){ int y=fa[x],z=fa[y]; bool flag=(ch[y][1]==x); ch[y][flag]=ch[x][!flag]; fa[ch[y][flag]]=y; ch[x][!flag]=y; fa[ch[x][!flag]]=x; fa[x]=z; ch[z][ch[z][1]==y]=x; pushup(y); pushup(x);}inline void splay(int x,int goal){ for(int y;(y=fa[x])!=goal;rotate(x)) { int z=fa[y]; if(z!=goal) { if((ch[z][0]==y)^(ch[y][0]==x))rotate(x); else rotate(y); } } if(!goal)rt=x; pushup(x);}inline void rotateto(int k,int goal){ int x=rt; while(1) { pushdown(x); if(k<sz[ch[x][0]]+1)x=ch[x][0]; else if(k>sz[ch[x][0]]+1)k-=sz[ch[x][0]]+1,x=ch[x][1]; else break; } splay(x,goal);}inline void newnode(int &r,int val){ r=++cnt; minum[r]=v[r]=val; sz[r]=1;}void build(int &r,int L,int R,int f){ int mid=(L+R)/2; newnode(r,a[mid]); fa[r]=f; if(L==R)return; if(L<mid)build(ch[r][0],L,mid-1,r); if(mid<R)build(ch[r][1],mid+1,R,r); pushup(r);}inline void ADD(int L,int R,int d){ rotateto(L,0); rotateto(R+2,rt); int u=ch[ch[rt][1]][0]; delta[u]+=d,v[u]+=d,minum[u]+=d;}inline void REVERSE(int L,int R){ rotateto(L,0); rotateto(R+2,rt); int u=ch[ch[rt][1]][0]; rev[u]^=1;}inline void REVOLVE(int L,int R,int d){ int rd=(d%(R-L+1)+(R-L+1))%(R-L+1),u; if(!rd)return; rotateto(L,0); rotateto(R-rd+2,rt); u=ch[ch[rt][1]][0]; ch[ch[rt][1]][0]=0; pushup(ch[rt][1]); pushup(rt); rotateto(L+rd,0); rotateto(L+rd+1,rt); ch[ch[rt][1]][0]=u; fa[u]=ch[rt][1]; pushup(ch[rt][1]); pushup(rt);}inline void INSERT(int x,int val){ rotateto(x+1,0); rotateto(x+2,rt); newnode(ch[ch[rt][1]][0],val); fa[ch[ch[rt][1]][0]]=ch[rt][1]; pushup(ch[rt][1]); pushup(rt);}inline void DELETE(int x){ rotateto(x,0); rotateto(x+2,rt); ch[ch[rt][1]][0]=0; pushup(ch[rt][1]); pushup(rt);}inline int MIN(int L,int R){ rotateto(L,0); rotateto(R+2,rt); return minum[ch[ch[rt][1]][0]];}int main(){ GET(n); for(int i=1;i<=n;++i) GET(a[i]); build(rt,0,n+1,0); GET(m); while(m--) { memset(op,0,sizeof op); scanf("%s",op); if(op[0]=='A') { GET(x); GET(y); GET(z); ADD(x,y,z); } else if(op[5]=='S') { GET(x); GET(y); REVERSE(x,y); } else if(op[3]=='O') { GET(x); GET(y); GET(z); REVOLVE(x,y,z); } else if(op[0]=='I') { GET(x); GET(y); INSERT(x,y); } else if(op[0]=='D') { GET(x); DELETE(x); } else if(op[0]=='M') { GET(x); GET(y); printf("%d\n",MIN(x,y)); } }}
0 0
- POJ3580 SuperMemo(区间树)
- POJ3580 SuperMemo(Splay的区间操作)
- poj3580 SuperMemo 伸展树 splay
- poj3580 SuperMemo
- SuperMemo POJ3580
- POJ3580 SuperMemo
- poj3580 SuperMemo
- POJ3580 SuperMemo
- 【poj3580】 SuperMemo
- poj3580:SuperMemo(块状链表/Splay)
- poj3580 SuperMemo (Splay+区间内向一个方向移动)
- 【poj3580】【splay】SuperMemo
- poj3580 SuperMemo (splay)
- POJ3580 SuperMemo (Splay)
- POJ3580 SuperMemo(Splay)
- POJ3580 SuperMemo (Splay Tree的各种操作)
- 伸展树(区间加值,反转,循环移动,插入,删除区间,求区间最小值)poj3580
- 【Splay|Treap】poj3580 SuperMemo && bzoj1503 [noi2004]郁闷的出纳员
- JQuery插件之select2
- 《Head First设计模式》学习总结
- HTML 基础标签demo
- POJ 3664 Election Time
- Jquery写级联菜单
- POJ3580 SuperMemo(区间树)
- PropertyGrid控件基础
- Android的进程线程
- ClickOnce部署介绍(解决WinForm版本更新的问题)
- poj1125Stockbroker Grapevine【最短路】
- Qt中利用定时器QTimer准实时显示当前日期和时间
- 一个HTML游戏总结
- Linux find命令用法小结
- 栈的实现(链式)