poj 3580 SuperMemo 数据结构
2012-02-13 22:36
253 查看
题意:给一堆操作,维护数列。
思路:平衡树 splay
P.S. 太恶心了……
思路:平衡树 splay
P.S. 太恶心了……
#include<iostream> #include<cstring> #include<cmath> using namespace std; #define MAXN 110004 #define MAXM 110000 struct node { int left,right,father; int value,size,min; int adt; bool rev; }; int INF=987654321; int top=0; int n,m; node tree[MAXN+MAXM]; int tmp[MAXN]; int root; void update(int x) { if(x!=0) { tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1; tree[x].min=min(tree[tree[x].left].min,tree[tree[x].right].min); tree[x].min=min(tree[x].min,tree[x].value); } } void newnode(int lnum,int rnum,int value) { tree[++top].left=lnum; tree[top].right=rnum; tree[top].value=value; update(top); tree[rnum].father=tree[lnum].father=top; } int build_tree(int l,int r) { if(l>r) return 0; int mid=(l+r)/2; int lnum=build_tree(l,mid-1); int rnum=build_tree(mid+1,r); newnode(lnum,rnum,tmp[mid]); return top; } void pushdown(int x) { if(x!=0&&tree[x].rev) { swap(tree[x].left,tree[x].right); tree[tree[x].left].rev=!tree[tree[x].left].rev; tree[tree[x].right].rev=!tree[tree[x].right].rev; tree[x].rev=false; } if(x!=0&&tree[x].adt!=0) { tree[tree[x].left].adt+=tree[x].adt; tree[tree[x].right].adt+=tree[x].adt; if(tree[x].left!=0) tree[tree[x].left].min+=tree[x].adt; if(tree[x].right!=0) tree[tree[x].right].min+=tree[x].adt; tree[tree[x].left].value+=tree[x].adt; tree[tree[x].right].value+=tree[x].adt; tree[x].adt=0; } } void leftrotate(int x) { int y=tree[x].father; int z=tree[x].left; if(y==tree[tree[y].father].left) tree[tree[y].father].left=x; else tree[tree[y].father].right=x; tree[x].father=tree[y].father; tree[x].left=y; tree[y].father=x; tree[y].right=z; tree[z].father=y; update(y); update(x); } void rightrotate(int x) { int y=tree[x].father; int z=tree[x].right; if(y==tree[tree[y].father].right) tree[tree[y].father].right=x; else tree[tree[y].father].left=x; tree[x].father=tree[y].father; tree[x].right=y; tree[y].father=x; tree[y].left=z; tree[z].father=y; update(y); update(x); } void splay(int rootnew,int x) { pushdown(x); int y,z; int i=0; int fa=tree[rootnew].father; while(tree[x].father!=fa) { y=tree[x].father; z=tree[y].father; if(z==fa) { if(tree[y].left==x) rightrotate(x); else leftrotate(x); break; } if(tree[z].left==y) { if(tree[y].left==x) {rightrotate(y),rightrotate(x);} else leftrotate(x),rightrotate(x); } else { if(tree[y].left==x) rightrotate(x),leftrotate(x); else leftrotate(y),leftrotate(x); } } if(rootnew==root) root=x; } void find(int root,int pos) { int x=root; while(pushdown(x),tree[tree[x].left].size+1!=pos) { if(tree[tree[x].left].size>=pos) x=tree[x].left; else pos-=tree[tree[x].left].size+1, x=tree[x].right; } splay(root,x); } void add(int l,int r,int z) { find(root,l); find(tree[root].right,r-l); int p=tree[tree[root].right].left; tree[p].adt+=z; tree[p].value+=z; tree[p].min+=z; splay(root,p); } void reverse(int l,int r) { find(root,l); find(tree[root].right,r-l); int p=tree[tree[root].right].left; tree[p].rev=!tree[p].rev; } void revolve(int l,int r,int a) { find(root,l); find(tree[root].right,r-l); find(tree[tree[root].right].left,tree[tree[tree[root].right].left].size-a); find(tree[tree[tree[root].right].left].right,tree[tree[tree[tree[root].right].left].right].size); int p=tree[tree[root].right].left; int t=tree[tree[tree[root].right].left].right; tree[p].right=0; tree[tree[p].father].left=t; tree[t].father=tree[p].father; tree[t].right=p; tree[p].father=t; update(p); splay(root,p); } void insert(int pos,int value) { find(root,pos); find(tree[root].right,1); newnode(0,0,value); int p=tree[root].right; tree[p].left=top; tree[top].father=p; splay(root,top); } void del(int pos) { find(root,pos); find(tree[root].left,tree[tree[root].left].size); tree[tree[root].left].right=tree[root].right; tree[tree[root].right].father=tree[root].left; root=tree[root].left; tree[root].father=0; update(root); } int MIN(int l,int r) { find(root,l); find(tree[root].right,r-l); int p=tree[tree[root].right].left; return tree[p].min; } int main() { scanf("%d",&n); int i; int x,y,z; memset(tree,0,sizeof(tree)); tree[0].min=INF; tree[0].size=0; tmp[1]=INF; for(i=2;i<=n+1;i++) scanf("%d",tmp+i); tmp[n+2]=INF; root=build_tree(1,n+2); tree[root].father=0; scanf("%d",&m); char c[20]; for(i=1;i<=m;i++) { scanf("%s",c); if(strcmp(c,"ADD")==0) { scanf("%d%d%d",&x,&y,&z); add(x,y+2,z); } if(strcmp(c,"REVERSE")==0) { scanf("%d%d",&x,&y); reverse(x,y+2); } if(strcmp(c,"REVOLVE")==0) { scanf("%d%d%d",&x,&y,&z); if(z%(y-x+1)) revolve(x,y+2,z%(y-x+1)); } if(strcmp(c,"INSERT")==0) { scanf("%d%d",&x,&y); insert(x+1,y); } if(strcmp(c,"DELETE")==0) { scanf("%d",&x); del(x+1); } if(strcmp(c,"MIN")==0) { scanf("%d%d",&x,&y); printf("%d\n",MIN(x,y+2)); } } return 0; }
相关文章推荐
- 【POJ】3580 SuperMemo
- poj-3580-SuperMemo-splay
- POJ 3580 SuperMemo (splay tree)
- POJ 3580 SuperMemo
- POJ 3580——SuperMemo(Splay树,经典题)
- poj3580 SuperMemo
- POJ 3580 SuperMemo [Splay]
- 平衡树(Splay):Splaytree POJ 3580 SuperMemo
- POJ 3580 SuperMemo(splay)
- Splay树(多操作)——POJ 3580 SuperMemo
- poj-3580 SuperMemo[splay tree]
- POJ 3580 SuperMemo (Splay各种区间操作)
- POJ 数据结构(2)
- POJ 3580 SuperMemo
- poj 3468 A Simple Problem with Integers 数据结构
- POJ 3580(SuperMemo-Splay区间加)[template:Splay V2]
- POJ 3580-SuperMemo-splay树
- POJ 3580 OpenJ_Bailian 4090 SuperMemo (伸展树模版)
- POJ 3378——Crazy Thairs(树状数组+dp+高精度)数据结构优化的DP
- BZOJ 1895 & POJ 3580 supermemo (splay)