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

你可能感兴趣的:(poj)