学习了一手可持久化treap
#include<bits/stdc++.h> #define LL long long #define LD long double #define ull unsigned long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ALL(x) (x).begin(), (x).end() #define fio ios::sync_with_stdio(false); cin.tie(0); using namespace std; const int N = 2e5 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); template<class T, class S> inline void add(T &a, S b) {a += b; if(a >= mod) a -= mod;} template<class T, class S> inline void sub(T &a, S b) {a -= b; if(a < 0) a += mod;} template<class T, class S> inline bool chkmax(T &a, S b) {return a < b ? a = b, true : false;} template<class T, class S> inline bool chkmin(T &a, S b) {return a > b ? a = b, true : false;} mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()); int n, m, init, root, top, v[N]; struct Treap { #define l(u) a[u].ch[0] #define r(u) a[u].ch[1] struct Node { int ch[2]; int val, sz; LL sum; }; int tot; Node a[2750000]; inline int NewNode(int x) { tot++; a[tot].ch[0] = a[tot].ch[1] = 0; a[tot].val = a[tot].sum = x; a[tot].sz = 1; return tot; } inline int CpyNode(int id) { tot++; a[tot] = a[id]; return tot; } inline void pull(int u) { a[u].sz = a[l(u)].sz + a[r(u)].sz + 1; a[u].sum = a[l(u)].sum + a[r(u)].sum + a[u].val; } void Split(int w, int k, int &u, int &v) { if(!w) { u = v = 0; return; } if(k >= a[l(w)].sz + 1) { u = CpyNode(w); Split(r(w), k - a[l(w)].sz - 1, r(u), v); pull(u); } else { v = CpyNode(w); Split(l(w), k, u, l(v)); pull(v); } } void Merge(int &w, int u, int v) { if(!u || !v) { w = u | v; return; } if(rng() % (a[u].sz + a[v].sz) < a[u].sz) { w = CpyNode(u); Merge(r(w), r(u), v); } else { w = CpyNode(v); Merge(l(w), u, l(v)); } pull(w); } LL query(int &u, int l, int r) { int L, M, R; Split(u, r, L, R); Split(L, l - 1, L, M); LL ret = a[M].sum; Merge(L, L, M); Merge(u, L, R); return ret; } void update1(int &u, int l, int r, int k) { int L1, R1, M1, L2, R2, M2; Split(u, l - 1, L1, R1); Split(L1, l - k - 1, L1, M1); Split(u, r, L2, R2); Split(L2, l - 1, L2, M2); while(a[M1].sz < r - l + 1) Merge(M1, M1, M1); Split(M1, r - l + 1, M1, M2); Merge(L2, L2, M1); Merge(u, L2, R2); } void update2(int &u, int v, int l, int r) { int L1, M1, R1, L2, M2, R2; Split(u, r, L1, R1); Split(L1, l - 1, L1, M1); Split(v, r, L2, R2); Split(L2, l - 1, L2, M2); Merge(L1, L1, M2); Merge(u, L1, R1); } void build(int &u, int l, int r) { if(l > r) { u = 0; return; } int mid = l + r >> 1; u = NewNode(v[mid]); build(l(u), l, mid - 1); build(r(u), mid + 1, r); pull(u); } void dfs(int u) { if(!u) return; dfs(l(u)); v[++top] = a[u].val; dfs(r(u)); } void ReBuild() { tot = a[init].sz; top = 0; dfs(root); build(root, 1, n); } } treap; int main() { scanf("%d%d", &n, &m); for(int i = 1; i <= n; i++) { scanf("%d", &v[i]); } treap.build(init, 1, n); root = init; int op, l, r, k; while(m--) { scanf("%d%d%d", &op, &l, &r); if(op == 1) { printf("%lld\n", treap.query(root, l, r)); } else if(op == 2) { scanf("%d", &k); treap.update1(root, l, r, k); } else { treap.update2(root, init, l, r); } if(treap.tot >= 2500000) { treap.ReBuild(); } } return 0; } /* */