hdu 4348 To the moon

题意: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 }

 

posted @ 2016-11-06 14:31  llysrv  阅读(137)  评论(0编辑  收藏  举报