POJ 3468 【线段树 成段更新 求区间和】.cpp

题意:

  给出一些值 然后给出你一些命令 按照命令输出

  命令:

  C a b c 表示更新a ~ b的值加上 c

  Q a b 表示查询a~b的和

输入:

  n m 表示有n个数 m 个操作

  接下来 m 行为命令行

 

思路:

  就是简单的线段树成段更新求和  

 

Tips:

  ※ 询问的时候要 pushdown

  ※ 注意范围问题吖~

 

Code:

  

View Code
 1 #include <stdio.h>
 2 #include <cstring>
 3 using namespace std;
 4 #define LL long long
 5 
 6 const int MAXN = 100010;
 7 LL sum[MAXN<<2], lazy[MAXN<<2];
 8 
 9 void pushup(int rt)
10 {
11     sum[rt] = sum[rt<<1]+sum[rt<<1|1];
12 }
13 
14 void pushdown(int rt, int x)
15 {
16     if(lazy[rt] != 0) {
17         lazy[rt<<1] += lazy[rt];
18         lazy[rt<<1|1] += lazy[rt];
19         sum[rt<<1] += (LL)(x-(x>>1))*lazy[rt];
20         sum[rt<<1|1] += (LL)(x>>1)*lazy[rt];
21         lazy[rt] = 0;
22     }
23 }
24 
25 void creat(int l, int r, int rt)
26 {
27     lazy[rt] = 0;
28     if(l == r) {
29         scanf("%lld", &sum[rt]);
30         return;
31     }
32     int mid = (l+r)>>1;
33     creat(l, mid, rt<<1);
34     creat(mid+1, r, rt<<1|1);
35     pushup(rt);
36 }
37 
38 void modify(int l, int r, int x, int L, int R, int rt)
39 {
40     if(l <= L && r >= R) {
41         lazy[rt] += (LL)x;
42         sum[rt] += (LL)x*(R-L+1);
43         return;
44     }
45     pushdown(rt, R-L+1);
46     int mid = (L+R)>>1;
47     if(l <= mid) modify(l, r, x, L, mid, rt<<1);
48     if(r > mid) modify(l, r, x, mid+1, R, rt<<1|1);
49     pushup(rt);
50 }
51 
52 LL query(int l, int r, int L, int R, int rt)
53 {
54     if(l <= L && r >= R) {
55         return (LL)sum[rt];
56     }
57     pushdown(rt, R-L+1);///!!!!
58     int mid = (L+R)>>1;
59     LL ans = 0;
60     if(l <= mid) ans += query(l, r, L, mid, rt<<1);
61     if(r > mid) ans += query(l, r, mid+1, R, rt<<1|1);
62     return ans;
63 }
64 
65 int main()
66 {
67     int i, j, k;
68     int n, m;
69     int a, b, c;
70     char opt[2];
71     while(scanf("%d %d", &n, &m) != EOF) {
72         creat(1, n, 1);
73         while(m--) {
74             scanf("%s %d %d", opt, &a, &b);
75             if(opt[0] == 'Q') {
76                 printf("%lld\n", query(a, b, 1, n, 1));
77             } else if (opt[0] == 'C') {
78                 scanf("%d", &c);
79                 modify(a, b, c, 1, n, 1);
80             }
81         }
82     }
83     return 0;
84 }

 

题目链接:http://poj.org/problem?id=3468

posted @ 2012-10-17 21:37  Griselda.  阅读(318)  评论(0)    收藏  举报