题目:http://poj.org/problem?id=3580
View Code
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int M = 300000+10; const int inf = 0x3f3f3f3f; #define type int struct node { int size, rev; type key, minv, delta; node *ch[2], *pre; void add(type v) { if (size == 0)return; delta += v, minv += v, key += v; } void reverse() { if (size == 0)return; rev ^= 1; swap(ch[0], ch[1]); } void update() { size = ch[0]->size + ch[1]->size + 1; minv = min(key, min(ch[0]->minv, ch[1]->minv)); } void pushdown() { if (delta) { ch[0]->add(delta); ch[1]->add(delta); } if (rev) { ch[0]->reverse(); ch[1]->reverse(); } delta = rev = 0; } }; type arr[M]; node * hash[M]; #define keytree root->ch[1]->ch[0] class Splay { int cnt, top; node *stk[M], data[M]; public: node *newnode(type var) { node *p; if (top) p = stk[top--]; else p = &data[cnt++]; p->key = p->minv = var; p->size = 1; p->delta = p->rev = 0; p->ch[0] = p->ch[1] = p->pre = null; return p; } void init() { top = cnt = 0; null = newnode(inf); null->size = 0; root = newnode(inf); root->ch[1] = newnode(inf); root->ch[1]->pre = root; root->update(); } void maketree(int l, int r) { init(); keytree = build(l, r); keytree->pre = root->ch[1]; splay(keytree, null); } node *build(int l, int r) { if (l > r) return null; int mid = (l + r) >> 1; node *p = newnode(arr[mid]); hash[arr[mid]] = p; p->ch[0] = build(l, mid-1); p->ch[1] = build(mid+1, r); if (p->ch[0] != null) p->ch[0]->pre = p; if (p->ch[1] != null) p->ch[1]->pre = p; p->update(); return p; } void rotate(node *x, int c) { node *y = x->pre; y->pushdown(); x->pushdown(); y->ch[!c] = x->ch[c]; if (x->ch[c] != null) x->ch[c]->pre = y; x->pre = y->pre; if (y->pre != null) y->pre->ch[ y==y->pre->ch[1] ] = x; x->ch[c] = y; y->pre = x; y->update(); if (y == root) root = x; } void splay(node *x, node *f) { x->pushdown(); while (x->pre != f) { if (x->pre->pre == f) { rotate(x, x->pre->ch[0] == x); break; } node *y = x->pre; node *z = y->pre; int c = (y == z->ch[0]); if (x == y->ch[c]) { rotate(x, !c); rotate(x, c); } else { rotate(y, c); rotate(x, c); } } x->update(); } void select(int kth, node *x) { node * cur = root; while (true) { cur->pushdown(); int tmp = cur->ch[0]->size; if (tmp == kth) break; else if (tmp < kth) kth -= tmp + 1, cur = cur->ch[1]; else cur = cur -> ch[0]; } splay(cur, x); } void insert(int x, type y) { select(x, null); select(x+1, root); keytree = newnode(y); keytree->pre = root->ch[1]; root->ch[1]->update(); splay(keytree, null); } void insert(int x, int l, int r) { select(x, null); select(x+1, null); keytree = build(l, r); keytree->pre = root->ch[1]; root->ch[1]->update(); splay(keytree, null); } void erase(node *x) { if (x == null)return ; erase(x->ch[0]); erase(x->ch[1]); stk[++top] = x; } void dele(int x, int y) { select(x-1, null); select(y+1, root); erase(keytree); keytree = null; root->ch[1]->update(); root->update(); } void dele(int x) { select(x, null); deleroot(); } void dele(node * t) { splay(t, null); deleroot(); } void deleroot() { node *oldroot = root; root = root->ch[1]; root->pre = null; select(0, null); root->ch[0] = oldroot->ch[0]; root->ch[0]->pre = root; root->update(); stk[++top] = oldroot; } void add(int x, int y, type d) { select(x-1, null); select(y+1, root); keytree->add(d); splay(keytree, null); } void reverse(int x, int y) { select(x-1, null); select(y+1, root); keytree->reverse(); } void revolve(int x, int y, int d) { int len = y-x+1; d = (d % len + len) % len; if (d == 0) return ; if (d == 1) { dele(y); insert(x-1, stk[top]->key); } else { select(y-d+1, null); select(y+1, root); select(x-1, root); select(y, root->ch[1]); node *p = root->ch[0]->ch[1]; root->ch[0]->ch[1] = null; root->ch[0]->update(); root->ch[1]->ch[0]->ch[1] = p; p->pre = root->ch[1]->ch[0]; splay(p, null); } } type getMin(int x, int y) { select(x-1, null); select(y+1, root); return keytree->minv; } int query(type i) { splay(hash[i], null); int ans = root->ch[0]->size; return ans; } void debug() { vis(root); } void vis(node* t) { if (t == null) return; vis(t->ch[0]); printf("node%2d:lson %2d,rson %2d,pre %2d,sz=%2d,key=%2d\n", t - data, t->ch[0] - data, t->ch[1] - data, t->pre - data, t->size, t->key); vis(t->ch[1]); } node *root, *null; } spt; int main() { freopen("D:/a.txt", "r", stdin); int n, m, x, y, z; char op[20]; while (~scanf("%d", &n)) { for (int i=1; i<=n; i++) scanf("%d", &arr[i]); spt.init(); if (n > 0) { node *troot = spt.build(1, n); spt.keytree = troot; troot->pre = spt.root->ch[1]; spt.splay(troot, spt.null); } scanf("%d", &m); for (int i=1; i<=m; i++) { scanf("%s", op); if (!strcmp(op, "ADD")) { scanf("%d%d%d", &x, &y, &z); spt.add(x, y, z); } else if (!strcmp(op, "REVERSE")) { scanf("%d%d", &x, &y); spt.reverse(x, y); } else if (!strcmp(op, "REVOLVE")) { scanf("%d%d%d", &x, &y, &z); spt.revolve(x, y, z); } else if (!strcmp(op, "INSERT")) { scanf("%d%d", &x, &y); spt.insert(x, y); } else if (!strcmp(op, "DELETE")) { scanf("%d", &x); spt.dele(x); } else { scanf("%d%d", &x, &y); printf("%d\n", spt.getMin(x, y)); } } } return 0; }