POJ 3468 A Simple Problem with Integers 线段树

线段树

View Code
  1 /*

  2     poj3468

  3 */

  4 #include <iostream>

  5 using namespace std;

  6 const int N = 100005;

  7 

  8 struct node

  9 {

 10     int left, right;

 11     long long  num, add;

 12 }tree[4*N];

 13 

 14 int L(int n)

 15 {

 16     return n<<1;

 17 }

 18 int R (int n)

 19 {

 20     return (n<<1) | 1;

 21 }

 22 void update(int step)    //若当前节点的标志位add有值,则更新其左右节点

 23 {

 24     tree[L(step)].num += tree[step].add * (tree[L(step)].right - tree[L(step)].left + 1);

 25     tree[L(step)].add += tree[step].add;    //将标志位传给子节点

 26     tree[R(step)].num += tree[step].add * (tree[R(step)].right - tree[R(step)].left + 1);

 27     tree[R(step)].add += tree[step].add;

 28     tree[step].add = 0;                        //父节点清0

 29 }

 30 int a[N];

 31 

 32 void build(int l, int r, int step)    

 33 {

 34     tree[step].left = l;

 35     tree[step].right = r;

 36     tree[step].add = 0;

 37     if (l == r)        //到达叶子节点了

 38     {

 39         tree[step].num = a[l];

 40         return;

 41     }

 42     int mid = (l + r) >> 1;

 43     build(l, mid, L(step));

 44     build(mid+1, r, R(step));

 45     //其构造是自下而上(先求出其子节点的值),那么其父亲节点很明显就是其左右节点值的和

 46     tree[step].num = tree[L(step)].num + tree[R(step)].num;

 47 }

 48 

 49 void insert(int l, int r, int step, int add)

 50 {

 51     if (l<= tree[step].left && tree[step].right <= r)

 52     {

 53         tree[step].add += add;    

 54         tree[step].num += add * (tree[step].right - tree[step].left + 1);    //add * len

 55         return;

 56     }

 57     if (tree[step].add != 0)    //

 58     {

 59         update(step);

 60     }

 61     int mid = (tree[step].left + tree[step].right) >> 1;

 62     if (mid >= l) 

 63         insert(l, r, L(step), add);

 64     if (mid < r)

 65         insert(l, r, R(step), add);

 66     //由于可能其子节点有更新,我们需要在重新计算一次step这层的值

 67     tree[step].num = tree[L(step)].num + tree[R(step)].num;

 68 }

 69 

 70 long long  query(int l, int r, int step)

 71 {

 72     long long ans = 0;

 73     if (l <= tree[step].left && tree[step].right <= r)

 74     {

 75         return tree[step].num;

 76     }

 77     if (tree[step].add != 0)

 78     {

 79         update(step);

 80     }

 81     int mid = (tree[step].left + tree[step].right) >> 1;

 82     if (mid >= l)    //与左节点有交集

 83         ans += query(l, r, L(step));

 84     if (mid < r)    //与右节点有交集

 85         ans += query(l, r, R(step));

 86     return ans;

 87 }

 88 

 89 int main()

 90 {

 91     int  n, q, i, k, l, r, add;

 92     char str;

 93 

 94     scanf("%d%d", &n, &q);

 95     for (i=1; i<=n; i++)

 96         scanf("%d", &a[i]);

 97     build(1, n, 1);

 98     

 99     while (q--)

100     {

101         getchar();

102         scanf("%c", &str);

103     //    printf("----->%c\n",str);

104         if (str == 'Q')

105         {

106             scanf("%d%d", &l, &r);

107             printf("%lld\n", query(l, r, 1));

108         }

109         else 

110         {

111             scanf("%d%d%d", &l, &r, &add);

112             insert(l, r, 1, add);

113         }

114         

115     }

116 

117     return 0;

118 }

 

你可能感兴趣的:(Integer)