题意:n个数 m次操作
操作分别为
C l r d: 把区间[l, r] 加 d
Q l r : 查询区间[l, r]的和
H l r t: 查询时间t的时候[l, r]的和
B t: 回到时间t
思路:主席树区间修改,区间求和
1 const int maxn = 100000 + 10; 2 const int maxnode = 25 * maxn; 3 4 int n, m; 5 6 struct Node 7 { 8 int l, r; 9 LL sum, add; 10 } tr[maxnode]; 11 int tail; 12 LL a[maxn]; 13 LL qL, qR, value; 14 LL sum; 15 16 #define lson tr[o].l,L,M 17 #define rson tr[o].r,M+1,R 18 #define self o,L,R 19 #define lc tr[o].l 20 #define rc tr[o].r 21 22 void build(int o, int L, int R) 23 { 24 if (L == R) 25 { 26 tr[o].sum = a[L]; 27 return; 28 } 29 tr[o].l = ++tail; 30 tr[o].r = ++tail; 31 int M = L + (R - L) / 2; 32 build(lson); 33 build(rson); 34 tr[o].sum = tr[lc].sum + tr[rc].sum; 35 } 36 37 void maintain(int o, int L, int R) 38 { 39 if (L < R) 40 { 41 tr[o].sum = tr[lc].sum + tr[rc].sum; 42 } 43 else tr[o].sum = a[L]; 44 tr[o].sum += tr[o].add * (R - L + 1); 45 } 46 47 void update(int& o, int L, int R) 48 { 49 tr[++tail] = tr[o]; 50 o = tail; 51 if (qL <= L && R <= qR) 52 { 53 tr[o].add += value; 54 } 55 else 56 { 57 int M = L + (R - L) / 2; 58 if (qL <= M) update(lson); 59 if (qR > M) update(rson); 60 } 61 maintain(self); 62 } 63 64 void query(int o, int L, int R, int add) 65 { 66 if (qL <= L && R <= qR) 67 { 68 sum += tr[o].sum + add * (R - L + 1); 69 return; 70 } 71 int M = L + (R - L) / 2; 72 if (qL <= M) query(lson, add + tr[o].add); 73 if (qR > M) query(rson, add + tr[o].add); 74 } 75 76 int root[maxn];//表示第i个线段树的root是什么,显然root[0]=0 77 78 void init() 79 { 80 memset(tr, 0, sizeof(tr)); 81 tail = 0; 82 for (int i = 1; i <= n; i++) 83 { 84 scanf("%lld", &a[i]); 85 } 86 root[0] = 0; 87 build(0, 1, n); 88 } 89 90 void solve() 91 { 92 char op[5]; 93 int t; 94 int i = 0; 95 while (m--) 96 { 97 op[0] = 0; 98 scanf("%s", op); 99 if (op[0] == ‘Q‘) 100 { 101 scanf("%lld%lld", &qL, &qR); 102 sum = 0; 103 query(root[i], 1, n, 0); 104 printf("%lld\n", sum); 105 106 } 107 else if (op[0] == ‘C‘) 108 { 109 i++; 110 root[i] = root[i-1]; 111 scanf("%lld%lld%lld", &qL, &qR, &value); 112 update(root[i], 1, n); 113 } 114 else if (op[0] == ‘H‘) 115 { 116 scanf("%lld%lld%d", &qL, &qR, &t); 117 sum = 0; 118 query(root[t], 1, n, 0); 119 printf("%lld\n", sum); 120 } 121 else 122 { 123 scanf("%d", &t); 124 i = t; 125 } 126 } 127 } 128 129 int main() 130 { 131 while (scanf("%d%d", &n, &m) == 2) 132 { 133 init(); 134 solve(); 135 } 136 return 0; 137 }
时间: 2024-11-09 06:32:21