POJ3468A Simple Problem with Integers(区间加数求和 + 线段树)

题目链接

题意:两种操作:一是指定区间的数全都加上一个数,二是统计指定区间的和

 

参考斌神的代码

  1 #include <iostream>
  2 #include <cstring>
  3 #include <algorithm>
  4 #include <cstdio>
  5 using namespace std;
  6 const int Max = 100000;
  7 const int INF = 0x3f3f3f3f;
  8 typedef long long LL;
  9 struct node
 10 {
 11     int l,r;
 12     LL inc; //记录这个区间所要增加的值
 13     LL sum;
 14 };
 15 node tree[Max * 4];
 16 int num[Max + 5];
 17 int n,q;
 18 void buildTree(int left, int right, int k)
 19 {
 20     tree[k].inc = 0;
 21     tree[k].tag = INF;
 22     tree[k].l = left;
 23     tree[k].r = right;
 24     if(left == right)
 25     {
 26         tree[k].sum = num[left];
 27         return ;
 28     }
 29     int mid = (left + right) / 2;
 30     buildTree(left, mid, k * 2);
 31     buildTree(mid + 1, right, k * 2 + 1);
 32     tree[k].sum = tree[k * 2].sum + tree[k * 2 + 1].sum;
 33 }
 34 void upDate(int left, int right, int k, int add)
 35 {
 36     if(tree[k].l == left && tree[k].r == right)
 37     {
 38         tree[k].inc += add; //仅仅记录一下该区间所要增加的值而已
 39         //tree[k].tag = add;
 40         return;
 41     }
 42     tree[k].sum += (right - left + 1) * add; //对于这样的大区间,就要求出sum
 43     int mid = (tree[k].l + tree[k].r) / 2;
 44     if(right <= mid)
 45     {
 46         upDate(left, right, k * 2, add);
 47     }
 48     else if(mid < left)
 49     {
 50         upDate(left, right, k * 2 + 1, add);
 51     }
 52     else
 53     {
 54         upDate(left, mid, k * 2, add);
 55         upDate(mid + 1, right, k * 2 + 1, add);
 56     }
 57 }
 58 LL Search(int left, int right, int k)
 59 {
 60     if(right < left)
 61         return 0;
 62     if(left == tree[k].l && right == tree[k].r)
 63     {
 64         return tree[k].sum + (right - left + 1) * tree[k].inc; //原来的和 + 增加的数的和 
 65     }
 66     tree[k].sum += (tree[k].r - tree[k].l + 1) * tree[k].inc;  //跟新sum的值 ,
 67     int mid = (tree[k].l + tree[k].r) / 2;
 68     upDate(tree[k].l, mid, k * 2, tree[k].inc);
 69     upDate(mid + 1, tree[k].r, k * 2 + 1, tree[k].inc);
 70     tree[k].inc = 0;
 71     if(right <= mid)
 72     {
 73         return Search(left, right, k * 2);
 74     }
 75     else if(mid < left)
 76     {
 77         return Search(left, right, k * 2 + 1);
 78     }
 79     else
 80     {
 81         return Search(left, mid, k * 2) + Search(mid + 1, right, k * 2 + 1);
 82     }
 83 }
 84 int main()
 85 {
 86     scanf("%d%d", &n, &q);
 87     for(int i = 1; i <= n; i++)
 88         scanf("%d", &num[i]);
 89     buildTree(1, n, 1);
 90     char opt[3];
 91     int a,b,add;
 92     while(q--)
 93     {
 94         scanf("%s", opt);
 95         if(strcmp(opt, "Q") == 0)
 96         {
 97             scanf("%d%d", &a, &b);
 98 
 99             printf("%I64d\n", Search(a, b, 1));
100         }
101         else
102         {
103             scanf("%d%d%d", &a, &b, &add);
104             upDate(a, b, 1, add);
105         }
106     }
107     return 0;
108 }
View Code

 

你可能感兴趣的:(POJ3468A Simple Problem with Integers(区间加数求和 + 线段树))