1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
| #include<bits/stdc++.h> using namespace std; #define endl '\n' #define FL(a, b, c) for(int a = (b), a##end = (c); a <= a##end; a++) #define FR(a, b, c) for(int a = (b), a##end = (c); a >= a##end; a--) #define lowbit(x) ((x) & -(x)) #define eb emplace_back #define ll long long constexpr int mod = 1e9 + 7, M = 4e6, N = 5e5; int addm(ll x, ll y, ll mod = mod){ll w = x + y; return (w >= mod) ? (w - mod) : w;} #define zadd(x, y) x = addm(x, y) mt19937 myrd(1497426); #define rd(r) uniform_int_distribution<int>(1, r)(myrd) int a[N]; struct node{int ls, rs, rev, size, cov, add, sum, val;}d[M]; int tot; int newnode(int val){ int w = ++tot; d[w].size = 1, d[w].add = d[w].ls = d[w].rs = d[w].rev = 0; d[w].sum = d[w].val = val, d[w].cov = -1; return w; } void copynode(int&i, int j){j ? (d[i = newnode(0)] = d[j], 1) : (i = 0);} void pushup(int x){ if(!x)return; d[x].sum = addm(addm(d[d[x].ls].sum, d[d[x].rs].sum), d[x].val); d[x].size = d[d[x].ls].size + d[d[x].rs].size + 1; } int build(int l, int r){ if(l > r)return 0; if(l == r)return newnode(a[l]); int mid = l + r >> 1, z = newnode(a[mid]); d[z].ls = build(l, mid - 1), d[z].rs = build(mid + 1, r); return pushup(z), z; } void rev(int x){if(x)swap(d[x].ls, d[x].rs), d[x].rev ^= 1;} void add(int x, int v){if(x)d[x].sum = addm(d[x].sum, 1LL * d[x].size * v % mod), zadd(d[x].add, v), zadd(d[x].val, v);} void cover(int x, int v){if(x)d[x].sum = (1LL * d[x].size * v) % mod, d[x].val = d[x].cov = v, d[x].add = 0;} void pushdown(int x){ int&ls = d[x].ls, &rs = d[x].rs, &a = d[x].add, &cov = d[x].cov; if(d[x].rev || a || ~cov)copynode(ls, ls), copynode(rs, rs); if(d[x].rev)rev(ls), rev(rs), d[x].rev = 0; if(~cov)cover(ls, cov), cover(rs, cov), cov = -1; if(a)add(ls, a), add(rs, a), a = 0; } void split(int x, int k, int&L, int&R){ if(!x)return void(L = R = 0); pushdown(x); if(d[d[x].ls].size >= k)copynode(R, x), split(d[R].ls, k, L, d[R].ls), pushup(R); else copynode(L, x), split(d[L].rs, k - d[d[x].ls].size - 1, d[L].rs, R), pushup(L); } int merge(int L, int R){ if(!L || !R)return L + R; if(rd(d[L].size + d[R].size) < d[L].size) return copynode(L, L), pushdown(L), d[L].rs = merge(d[L].rs, R), pushup(L), L; else return copynode(R, R), pushdown(R), d[R].ls = merge(L, d[R].ls), pushup(R), R; } void split(int root, int&L, int&mid, int&R, int l, int r){ split(root, r, L, R), split(L, l - 1, L, mid); } int root, n; int sum(int l, int r){ int L, mid, R, ans = 0; split(root, L, mid, R, l, r); ans = d[mid].sum, root = merge(L, merge(mid, R)); return ans; } void cover(int l, int r, int k){ int L, mid, R; split(root, L, mid, R, l, r), copynode(mid, mid); cover(mid, k), root = merge(L, merge(mid, R)); } void add(int l, int r, int k){ int L, mid, R; split(root, L, mid, R, l, r), copynode(mid, mid); add(mid, k), root = merge(L, merge(mid, R)); } void copy(int l1, int r1, int l2, int r2){ int L, lm, mid, rm, R; if(l1 < l2)split(root, L, rm, R, l2, r2), split(L, L, lm, mid, l1, r1), copynode(rm, lm); else split(root, L, rm, R, l1, r1), split(L, L, lm, mid, l2, r2), copynode(lm, rm); root = merge(L, merge(lm, merge(mid, merge(rm, R)))); } void swap(int l1, int r1, int l2, int r2){ int L, lm, mid, rm, R; if(l1 > l2)swap(l1, l2), swap(r1, r2); split(root, L, rm, R, l2, r2), split(L, L, lm, mid, l1, r1); root = merge(L, merge(rm, merge(mid, merge(lm, R)))); } void revers(int l, int r){ int L, mid, R; split(root, L, mid, R, l, r), copynode(mid, mid); rev(mid), root = merge(L, merge(mid, R)); } void dfs(int x){ if(!x)return; pushdown(x); dfs(d[x].ls), a[++n] = d[x].val, dfs(d[x].rs); } int32_t main(){ cin.tie(0)->sync_with_stdio(0); long long m, last = 0; cin >> n >> m; FL(i, 1, n)cin >> a[i]; root = build(1, n); FL(i, 1, m){ long long op, l1, l2 = 0, r1, r2 = 0; cin >> op >> l1 >> r1; if(op >= 2 && op <= 5)cin >> l2; if(op >= 4 && op <= 5)cin >> r2; switch(op){ case 1:cout << (last = sum(l1, r1)) << endl;break; case 2:cover(l1, r1, l2);break; case 3:add(l1, r1, l2);break; case 4:copy(l1, r1, l2, r2);break; case 5:swap(l1, r1, l2, r2);break; case 6:revers(l1, r1); } if(tot > 2e6)n = 0, dfs(root), tot = 0, root = build(1, n); } n = 0, dfs(root); FL(i, 1, n)cout << a[i] << " "; return 0; }
|