bzoj1895
fhqtreap
其实fhqtreap只有可持久化之后才用新建节点。。。
reverse和splay一样。
//#include<bits/stdc++.h> #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; typedef pair<int, int> PII; const int N = 200010; int n, root, cnt, m, last; int size[N], tag[N], a[100010], rnd[N]; int child[N][2]; ll mn[N], add[N], key[N]; void update(int x) { size[x] = size[child[x][0]] + size[child[x][1]] + 1; mn[x] = min(key[x], min(mn[child[x][0]], mn[child[x][1]])); } void pushdown(int x) { if(!x) return; if(add[x]) { add[child[x][0]] += add[x]; add[child[x][1]] += add[x]; mn[child[x][0]] += add[x]; mn[child[x][1]] += add[x]; key[child[x][0]] += add[x]; key[child[x][1]] += add[x]; add[x] = 0; } if(tag[x]) { tag[child[x][0]] ^= 1; tag[child[x][1]] ^= 1; swap(child[x][0], child[x][1]); tag[x] = 0; } } int newnode(int x) { ++cnt; size[cnt] = 1; rnd[cnt] = rand(); key[cnt] = x; mn[cnt] = x; return cnt; } int copy(int x) { ++cnt; size[cnt] = size[x]; rnd[cnt] = rnd[x]; tag[cnt] = tag[x]; mn[cnt] = mn[x]; add[cnt] = add[x]; child[cnt][0] = child[x][0]; child[cnt][1] = child[x][1]; key[cnt] = key[x]; return cnt; } int merge(int x, int y) { if(!x) return y; if(!y) return x; pushdown(x); pushdown(y); if(rnd[x] < rnd[y]) { child[x][1] = merge(child[x][1], y); update(x); return x; } else { child[y][0] = merge(x, child[y][0]); update(y); return y; } } PII split(int x, int k) { if(!x) return make_pair(0, 0); PII ret; pushdown(x); if(k <= size[child[x][0]]) { ret = split(child[x][0], k); child[x][0] = ret.second; ret.second = x; update(x); return ret; } else { ret = split(child[x][1], k - size[child[x][0]] - 1); child[x][1] = ret.first; ret.first = x; update(x); return ret; } } void Add(int l, int r, int d) { PII t1 = split(root, l - 1); PII t2 = split(t1.second, r - l + 1); key[t2.first] += d; add[t2.first] += d; mn[t2.first] += d; root = merge(t1.first, merge(t2.first, t2.second)); } void reverse(int l, int r) { int mid = r - l + 1; PII t1 = split(root, l - 1); PII t2 = split(t1.second, r - l + 1); tag[t2.first] ^= 1; root = merge(t1.first, merge(t2.first, t2.second)); } void revolve(int l, int r, int t) { if(t < 0) t = 0; t %= (r - l + 1); PII t1 = split(root, l - 1); PII t2 = split(t1.second, r - l + 1); PII t3 = split(t2.first, r - l + 1 - t); root = merge(t1.first, merge(merge(t3.second, t3.first), t2.second)); } void ins(int x, int p) { PII t1 = split(root, x); int a = newnode(p); root = merge(t1.first, merge(a, t1.second)); } void del(int x) { PII t1 = split(root, x - 1); PII t2 = split(t1.second, 1); root = merge(t1.first, t2.second); } void que(int l, int r) { PII t1 = split(root, l - 1); PII t2 = split(t1.second, r - l + 1); printf("%lld\n", mn[t2.first]); root = merge(t1.first, merge(t2.first, t2.second)); } void build(int &x, int l, int r) { if(l > r) return; int mid = (l + r) >> 1; x = newnode(a[mid]); build(child[x][0], l, mid - 1); build(child[x][1], mid + 1, r); update(x); } void print(int x) { if(!x) return; pushdown(x); print(child[x][0]); printf("%d ", key[x]); print(child[x][1]); } int main() { // freopen("supermemo8.in", "r", stdin); // freopen("output.txt", "w", stdout); srand(123456); scanf("%d", &n); for(int i = 1; i <= n; ++i) scanf("%d", &a[i]); mn[0] = 10000000000000ll; build(root, 1, n); scanf("%d", &m); while(m--) { char opt[10]; int l, r, d, x, t, p; scanf("%s", opt); if(opt[0] == 'A') { scanf("%d%d%d", &l, &r, &d); Add(l, r, d); } if(opt[2] == 'V' && opt[3] == 'E') { scanf("%d%d", &l, &r); reverse(l, r); } if(opt[3] == 'O') { scanf("%d%d%d", &l, &r, &t); revolve(l, r, t); } if(opt[0] == 'I') { scanf("%d%d", &x, &p); ins(x, p); } if(opt[0] == 'D') { scanf("%d", &x); del(x); } if(opt[0] == 'M') { scanf("%d%d", &l, &r); que(l, r); } // print(root); // puts(""); } // fclose(stdin); fclose(stdout); return 0; }