A Simple Problem with Integers (线段树 +lazy标记)

来源:互联网 发布:数控铣床四叶草的编程 编辑:程序博客网 时间:2024/06/01 07:22

上题:

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 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4
Sample Output
455915
Hint
The sums may exceed the range of 32-bit integers.
题意:就是普通的 改变和查区间和,算是一个 lazy标记的模板题,lazy标记 我在上篇博客已经特别不详细的说过了-。-,,,下面就说说我哪里错了吧 ,就是你一定要在更新和查询的时候向下更新你的状态(也就是父子节点的关系),而且你在更新完之后 是要向上更新父子节点的关系的
下面上代码:
#include<stdio.h>#include<iostream>#include<algorithm>#include<string.h>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int maxn=111111;long long sum[maxn<<2],mark[maxn<<2];void pushup(int rt){sum[rt]=sum[rt<<1]+sum[rt<<1|1];}void pushdown(int rt,int m){if(mark[rt]){mark[rt<<1]+=mark[rt];mark[rt<<1|1]+=mark[rt];sum[rt<<1]+=mark[rt]*(m-(m>>1));sum[rt<<1|1]+=mark[rt]*(m>>1);mark[rt]=0;}}void buildtree(int l,int r,int rt){mark[rt]=0;if(l==r){scanf("%lld",&sum[rt]);return ;}int m=(l+r)>>1;buildtree(lson);buildtree(rson);pushup(rt);}void update(int L,int R,int c,int l,int r,int rt){if(L<=l&&r<=R){mark[rt]+=c;sum[rt]+=(long long)c*(r-l+1);return ;}pushdown(rt,r-l+1);int m=(l+r)>>1;if(L<=m){update(L,R,c,lson);}if(R>m){update(L,R,c,rson);}pushup(rt);}  long long query(int L,int R,int l,int r,int rt){if(L<=l&&R>=r){return sum[rt];}pushdown(rt,r-l+1);long long ret=0;int m=(r+l)>>1;if(L<=m){ret+=query(L,R,lson);}if(R>m){ret+=query(L,R,rson);}return ret;}int main(){int n,m,a,b,c;char op[3];while(scanf("%d%d",&n,&m)!=EOF){memset(sum,0,sizeof(sum));memset(mark,0,sizeof(mark));buildtree(1,n,1);while(m--){cin>>op;if(op[0]=='Q'){scanf("%d%d",&a,&b);printf("%lld\n",query(a,b,1,n,1));}else {scanf("%d%d%d",&a,&b,&c);update(a,b,c,1,n,1);}}}}/*10 51 2 3 4 5 6 7 8 9 10Q 4 4Q 1 10Q 2 4C 3 6 3Q 2 4*/


0 0
原创粉丝点击