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


    题目连接:

      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
    ", res);
     97             }
     98             else
     99             {
    100                 scanf ("%I64d", &num);
    101                 insert (0, s, e, num);
    102             }
    103         }
    104     }
    105     return 0;
    106 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Oracle中的4大空值处理函数用法举例
    PyCharm安装
    Python安装与环境变量的配置
    多层分组排序问题
    将时间点的数据变成时间段的数据
    根据状态变化情况,求最大值和最小值
    ubuntu 源码安装 swig
    CSDN博客排名第一名,何许人也
    thinkPHP的常用配置项
    拔一拔 ExtJS 3.4 里你遇到的没遇到的 BUG(1)
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4611575.html
Copyright © 2020-2023  润新知