POJ 3580.SuperMemo
阿新 • • 發佈:2018-11-24
return down algo sta rand name ace pri amp
果斷寫了個 FHQ Treap……
犯了一些奇怪的錯誤……
- 一開始更新結點信息寫錯了。
- 標記下推的時候忘了左右子節點不存在的情況。
代碼:
#include <cstdio> #include <algorithm> #include <cstdlib> #define ls(p) tree[p].lson #define rs(p) tree[p].rson using namespace std; const int N = 1e5; const int M = 1e5; int n,m; struct node { int val,rnd,min,add,rev,sz; int lson,rson; } tree[N + M + 10]; inline int new_node(int v) { static int tot = 0; tree[++tot].val = tree[tot].min = v; tree[tot].rnd = rand(); tree[tot].sz = 1; return tot; } inline void up(int p) { tree[p].sz = tree[ls(p)].sz + 1 + tree[rs(p)].sz; tree[p].min = min(tree[p].val,min(tree[ls(p)].min,tree[rs(p)].min)); } inline void down(int p) { if(tree[p].add) { if(ls(p)) tree[ls(p)].val += tree[p].add,tree[ls(p)].min += tree[p].add,tree[ls(p)].add += tree[p].add; if(rs(p)) tree[rs(p)].val += tree[p].add,tree[rs(p)].min += tree[p].add,tree[rs(p)].add += tree[p].add; tree[p].add = 0; } if(tree[p].rev) { swap(ls(p),rs(p)); if(ls(p)) tree[ls(p)].rev ^= 1; if(rs(p)) tree[rs(p)].rev ^= 1; tree[p].rev = 0; } } int merge(int x,int y) { if(!x || !y) return x + y; down(x),down(y); if(tree[x].rnd < tree[y].rnd) { rs(x) = merge(rs(x),y); up(x); return x; } else { ls(y) = merge(x,ls(y)); up(y); return y; } } void split(int p,int k,int &x,int &y) { if(!p) { x = y = 0; return ; } down(p); if(tree[ls(p)].sz < k) x = p,split(rs(p),k - tree[ls(p)].sz - 1,rs(p),y); else y = p,split(ls(p),k,x,ls(p)); up(p); } int p,x,y,z,xx,yy; int main() { tree[0].min = 0x3f3f3f3f; srand(20070119); scanf("%d",&n); int v; for(register int i = 1;i <= n;++i) scanf("%d",&v),p = merge(p,new_node(v)); scanf("%d",&m); char op[10]; int a,b,c; while(m--) { scanf("%s",op); if(op[0] == 'A') { scanf("%d%d%d",&a,&b,&c); split(p,b,x,z); split(x,a - 1,x,y); tree[y].val += c,tree[y].min += c,tree[y].add += c; p = merge(merge(x,y),z); } else if(op[0] == 'R' && op[3] == 'E') { scanf("%d%d",&a,&b); split(p,b,x,z); split(x,a - 1,x,y); tree[y].rev ^= 1; p = merge(merge(x,y),z); } else if(op[0] == 'R' && op[3] == 'O') { scanf("%d%d%d",&a,&b,&c); int len = b - a + 1; c %= len; split(p,b,x,z); split(x,a - 1,x,y); split(y,len - c,xx,yy); p = merge(merge(x,merge(yy,xx)),z); } else if(op[0] == 'I') { scanf("%d%d",&a,&b); split(p,a,x,y); p = merge(merge(x,new_node(b)),y); } else if(op[0] == 'D') { scanf("%d",&a); split(p,a,x,z); split(x,a - 1,x,y); p = merge(x,z); } else { scanf("%d%d",&a,&b); split(p,b,x,z); split(x,a - 1,x,y); printf("%d\n",tree[y].min); p = merge(merge(x,y),z); } } }
POJ 3580.SuperMemo