码迷,mamicode.com
首页 > 其他好文 > 详细

暑期训练狂刷系列——poj 3468 A Simple Problem with Integers (线段树+区间更新)

时间:2015-06-30 21:53:56      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

题目连接:

  http://poj.org/problem?id=3468

题目大意:

  给出n个数,有两种操作:

    1:"C a b c",[a,b]中的每一个数都加上c。

    2:"Q a b",求[a,b]中每个数相加的和。

解题思路:

  线段树更新到每一个节点的话,由于节点数目和查询次数原因会tle,所以在每一个节点内定义一个标志变量表示当前节点的下一层为更新,每次查询时候有需要的话在更新到下一层。

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <iostream>
  4 #include <algorithm>
  5 using namespace std;
  6 const int maxn = 400010;
  7 const int INF = 0x3f3f3f3f;
  8 #define LL __int64
  9 struct node
 10 {
 11     LL L, R;
 12     LL sum, add;
 13     LL Mid()
 14     {
 15         return (L + R) / 2;
 16     }
 17 };
 18 node tree[maxn];
 19 LL res;
 20 
 21 void build(LL root, LL l, LL r)
 22 {
 23     tree[root].L = l;
 24     tree[root].R = r;
 25     tree[root].sum = tree[root].add = 0;
 26 
 27     if (l == r)
 28         return ;
 29     build (2*root+1, l, tree[root].Mid());
 30     build (2*root+2, tree[root].Mid()+1, r);
 31 }
 32 void insert (LL root, LL s, LL e, LL x)
 33 {
 34     tree[root].sum += x * (e - s + 1);
 35     if (tree[root].L == s && e == tree[root].R)//更新到区间
 36         {
 37             tree[root].add += x;
 38             return ;
 39         }
 40     if (e <= tree[root].Mid())
 41         insert (2*root+1, s, e, x);
 42     else if (tree[root].Mid() < s)
 43         insert (2*root+2, s, e, x);
 44     else
 45     {
 46         insert (2*root+1, s, tree[root].Mid(), x);
 47         insert (2*root+2, tree[root].Mid()+1, e, x);
 48     }
 49 }
 50 void query (LL root, LL s, LL e)
 51 {
 52 
 53     if (tree[root].L == s && e == tree[root].R)
 54     {
 55         res += tree[root].sum;
 56         return ;
 57     }
 58     if (tree[root].add)
 59     {//向下继续更新
 60         tree[2*root+1].add += tree[root].add;
 61         tree[2*root+2].add += tree[root].add;
 62         tree[2*root+1].sum += tree[root].add * (tree[2*root+1].R - tree[2*root+1].L + 1);
 63         tree[2*root+2].sum += tree[root].add * (tree[2*root+2].R - tree[2*root+2].L + 1);
 64         tree[root].add = 0;
 65     }
 66     if (e <= tree[root].Mid())
 67         query (2*root+1, s, e);
 68     else if (tree[root].Mid() < s)
 69         query (2*root+2, s, e);
 70     else
 71     {
 72         query (2*root+1, s, tree[root].Mid());
 73         query (2*root+2, tree[root].Mid()+1, e);
 74     }
 75 }
 76 int main ()
 77 {
 78     LL n, m, num;
 79     while (scanf ("%I64d %I64d", &n, &m) != EOF)
 80     {
 81         build (0, 1, n);
 82         for (int i=1; i<=n; i++)
 83         {
 84             scanf ("%I64d", &num);
 85             insert (0, i, i, num);
 86         }
 87         char str[2];
 88         LL s, e;
 89         while (m --)
 90         {
 91             scanf ("%s %I64d %I64d", str, &s, &e);
 92             if (str[0] == Q)
 93             {
 94                 res = 0;
 95                 query (0, s, e);
 96                 printf ("%I64d\n", res);
 97             }
 98             else
 99             {
100                 scanf ("%I64d", &num);
101                 insert (0, s, e, num);
102             }
103         }
104     }
105     return 0;
106 }

 

暑期训练狂刷系列——poj 3468 A Simple Problem with Integers (线段树+区间更新)

标签:

原文地址:http://www.cnblogs.com/alihenaixiao/p/4611575.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!