Time Limit: 5000MS   Memory Limit: 131072K
Total Submissions: 97008   Accepted: 30285
Case Time Limit: 2000MS

Description

You have N integers, A1A2, ... , AN. You need to deal with two kinds of operations. One type of operation is to add some given number to each number in a given interval. The other is
to ask for the sum of numbers in a given interval.

Input

The first line contains two numbers N and Q. 1 ≤ N,Q ≤ 100000.

The second line contains N numbers, the initial values of A1A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.

Each of the next Q lines represents an operation.

"C a b c" means adding c to each of AaAa+1, ... , Ab. -10000 ≤ c ≤ 10000.

"Q a b" means querying the sum of AaAa+1, ... , Ab.

Output

You need to answer all Q commands in order. One answer in a line.

Sample Input

10 5
1 2 3 4 5 6 7 8 9 10
Q 4 4
Q 1 10
Q 2 4
C 3 6 3
Q 2 4

Sample Output

4
55
9
15

Hint

The sums may exceed the range of 32-bit integers.

Source

【题解】

线段树的区间递增。

输入数据的时候,要用到build过程,只有到达最底端的节点的时候,才输入这个节点。然后要记得往上更新它的父亲节点。即由sum[左儿子],sum[右儿子],更新sum[爸爸]。

然后是懒惰标记的使用<=修改。

我们到达的这个节点,如果它所代表的区间,被所询问的区间所覆盖。则直接修改这个节点的sum值即可,至于它的儿子们,则只要标记一下即可(add[rt] = xx),等我们需要访问它的时候再往下更新即可。

其他的则没有啥了。

【代码】

#include <cstdio>

int n, q;
__int64 sum[100001 * 4] = { 0 }, add[100001 * 4] = { 0 }; //开4倍是保险的做法。 void downpush(int rt, int len)//查看rt这个节点有没有懒惰标记。如果有的话就给它的儿子们贴上标记,同时清楚这个
{//标记,同时更新儿子的sum信息。
if (add[rt] != 0)
{
add[rt << 1] += add[rt];//左儿子加上父节点的懒惰标记值。
add[rt << 1 | 1] += add[rt];//右儿子也要加上父节点的懒惰标记值。
sum[rt << 1] += (len - (len >> 1))*add[rt];//左儿子的sum值要根据懒惰标记改变。不能写成(len - (len >> 1))*add[rt<<1],因为可能add[rt<<1]
//在未加上add[rt]之前已经不等于0了,而那个add[rt<<1]之前是已经累加过的,不能重复累加。
//这里的len-(len >> 1)则是这个区间它的长度。给每个位置都加上add[rt]。总和就是....
sum[rt << 1 | 1] += (len >> 1)*add[rt];//右儿子则是同理。
add[rt] = 0;//懒惰标记已经操作过了。就置为0;
}
} void uppush(int rt) //这是对儿子节点进行操作过后。回溯父节点的时候更新sum[rt];
{
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
} void updata(int l, int r, int num, int begin, int end, int rt)//要求的区间是l,r,当前节点rt所代表的区间为begin,end;要增加的值为num;
{
if (l <= begin && end <= r) //如果当前这个节点所代表的区间被所要求的区间覆盖。那么就直接修改这个区间的和,然后加上懒惰标记
{//表示它的儿子节点们没有更新过。下次要记得更新。
add[rt] += num;
sum[rt] += (end - begin + 1)*num;//修改这个节点所代表的区间的区间和。
return;
}
downpush(rt, end - begin + 1);//看看这个节点有没有懒惰标记,如果有的话就先处理懒惰标记。
int m = (begin + end) >> 1;//获取中间节点。
if (l <= m)
updata(l, r, num, begin, m, rt << 1);//如果所要求的区间和当前这个节点所代表的区间的左半部分有交集,则递归往左递增。
//这样会不断地缩小区间。直到节点所代表的区间被那个交集覆盖(可能被分成了很多块)
if (m < r)//右边也是一样的,如果有小的区间有交集。则递归右边。
updata(l, r, num, m + 1, end, rt << 1 | 1);
uppush(rt);//这是用节点的儿子来更新节点的sum值。
} void build(int l, int r, int rt)//建树的过程<=>也即输入数据的过程(把数据输入到整棵树的最下面(叶子节点处)
{
if (l == r)
{
scanf("%I64d", &sum[rt]);//输入数据
return;
}
int mid = (l + r) >> 1;//获取中点
build(l, mid, rt << 1);//然后往左递归
build(mid + 1, r, rt << 1 | 1);//往右递归
uppush(rt);//然后根据儿子的sum信息来更新当前节点rt的sum信息。
} __int64 query(int l, int r, int begin, int end, int rt)//所询问的区间是l,r然后当前节点rt所代表的区间为begin,end;
{
if (l <= begin && end <= r)
{
return sum[rt];//如果当前节点所代表的区间被所询问的区间所覆盖,则直接返回这个区间的和。
}
downpush(rt, end - begin + 1);//如果这个节点有懒惰标记,则要往下更新儿子节点的sum值。
int mid = (begin + end) >> 1;//返回这个区间的中点
__int64 re = 0;
if (l <= mid)//如果这个节点所代表的区间的左半部分和所询问的区间有交集。则递归寻找那个交集。顺便把那个交集的和累加一下。
re += query(l, r, begin, mid, rt << 1);
if (mid < r)//这个是右边有交集的情况。也是一样累加右边的交集的区间和就可以了。
re += query(l, r, mid + 1, end, rt << 1 | 1);
return re;//返回总的区间和。
} int main()
{
//freopen("F:\\rush.txt", "r", stdin);
//freopen("F:\\rush_out.txt", "w", stdout);
scanf("%d%d", &n, &q);
build(1, n, 1); //输入n个数据
for (int i = 1; i <= q; i++)//输入q个操作。
{
char op[10];
scanf("%s", op);
int a, b, c;
if (op[0] == 'C')//如果是递增操作
{
scanf("%d%d%d", &a, &b, &c);
updata(a, b, c, 1, n, 1);//(a,b)的范围内都递增c。如果要递减,c就是负数,这点可以用在树状数组上面。
}
else
{
scanf("%d%d", &a, &b);//这是询问区间和。
printf("%I64d\n", query(a, b, 1, n, 1));
}
}
return 0;
}

【poj3468】A Simple Problem with Integers的更多相关文章

  1. 【poj3468】 A Simple Problem with Integers

    http://poj.org/problem?id=3468 (题目链接) 题意 给出一个序列,要求维护区间修改与区间求和操作. Solution 多年以前学习的树状数组区间修改又忘记了→_→. 其实 ...

  2. 【线段树成段更新成段查询模板】【POJ3468】A Simple Problem with Integerst

    题目大意: 2个操作 A.区间a b 增加 c B 查询a b; 注意事项:1.记住要清除标记 2.查询时要下放标记,但没必要向上更新 线段:自带的,不用建模 区间和性质:sum: /* WA 1次 ...

  3. 一本通1548【例 2】A Simple Problem with Integers

    1548:[例 2]A Simple Problem with Integers 题目描述 这是一道模板题. 给定数列 a[1],a[2],…,a[n],你需要依次进行 q 个操作,操作有两类: 1 ...

  4. POJ3468:A Simple Problem with Integers(线段树模板)

    A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 149972 ...

  5. 【POJ3468】【zkw线段树】A Simple Problem with Integers

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  6. 【POJ3468】【树状数组区间修改】A Simple Problem with Integers

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  7. 【POJ2761】【fhq treap】A Simple Problem with Integers

    Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. On ...

  8. 【成端更新线段树模板】POJ3468-A Simple Problem with Integers

    http://poj.org/problem?id=3468 _(:зゝ∠)_我又活着回来啦,前段时间太忙了写的题没时间扔上来,以后再说. [问题描述] 成段加某一个值,然后询问区间和. [思路] 讲 ...

  9. 【POJ 3468】 A Simple Problem with Integers

    [题目链接] 点击打开链接 [算法] 本题用线段树很容易写,但是,笔者为了练习树状数组,就用树状数组的方法做了一遍 我们不妨引入差分数组c, 则sum(n) = c[1] + (c[1] + c[2] ...

随机推荐

  1. linux创建新用户并给予root权限

    root比windows的系统管理员的能力更大,足以把整个系统的大部分文件删掉,导致系统完全毁坏,不能再次使用.所以,用root进行不当的操作是相当危险的,轻微的可以死机,严重的甚至不能开机.所以,在 ...

  2. WPF 入门《常用控件》

    1.GroupBox 注意: GroupBox仍然需要布局容器来放置元素.如: StackPanel面板 <GroupBox Header="select number?"& ...

  3. 41.关于Intellij IDEA菜单项中Compile、Make和Build的区别

    转自:https://www.cnblogs.com/ini_always/archive/2011/10/23/2221985.html Compile.Make和Build的区别   针对Java ...

  4. 使用Spring框架的好处

    转自:https://www.cnblogs.com/hoobey/p/6032506.html 在SSH框假中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JD ...

  5. 【Codeforces Round #450 (Div. 2) A】Find Extra One

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 模拟. 看看Y左边或右边的点个数是否<=1 [代码] #include <bits/stdc++.h> using ...

  6. [RxJS] How To get the results of two HTTP requests made in sequence

    switchMap can chain two HTTP requests together, creating one request based on the results of the fir ...

  7. (三)unity4.6Ugui中文教程文档-------概要-UGUI Basic Layout

     大家好,我是孙广东.   转载请注明出处:http://write.blog.csdn.net/postedit/38922399 更全的内容请看我的游戏蛮牛地址:http://www.unit ...

  8. 推荐一个iOS应用UI界面设计站点

    Patterns是一个分享ios应用UI界面的站点,专注于分享iOS应用UI界面的细节.依照设计元素进行分类,依照iOS经常使用功能对各类UI进行分类展示. 链接:url=http%3A%2F%2Fw ...

  9. zookeeper分布式协调服务的使用一

    Zookeeper是一个高性能,分布式的应用协调服务. 提供服务: 1.集群成员的管理(Group Membership) 2.分布式锁(Locking) 3.选主(Leader Election) ...

  10. 去哪网实习总结:用到的easyui组件总结(JavaWeb)

    本来是以做数据挖掘的目的进去哪网的,结构却成了系统开发... 只是还是比較认真的做了三个月,老师非常认同我的工作态度和成果.. . 实习立即就要结束了,总结一下几点之前没有注意过的变成习惯和问题,分享 ...