标签:des style color 使用 os io strong for
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 61636 | Accepted: 18840 | |
Case Time Limit: 2000MS |
Description
You have N integers, A1, A2, ... , 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 A1, A2, ... , AN. -1000000000 ≤ Ai ≤ 1000000000.
Each of the next Q lines represents an operation.
"C a b c" means adding c to each of Aa, Aa+1, ... , Ab. -10000 ≤ c ≤ 10000.
"Q a b" means querying the sum of Aa, Aa+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
题解及代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <set> #include <map> #include <queue> #include <string> #define maxn 100010 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define ALL %I64d using namespace std; typedef __int64 ll; struct segment { int l,r; ll value; ll nv; } son[maxn<<2]; void PushUp(int rt) { son[rt].value=son[rt<<1].value+son[rt<<1|1].value; } void Build(int l,int r,int rt) { son[rt].l=l; son[rt].r=r; son[rt].nv=0; if(l==r) { scanf("%I64d",&son[rt].value); return; } int m=(l+r)/2; Build(lson); Build(rson); PushUp(rt); } void Update_n(ll w,int l,int r,int rt) { if(son[rt].l==l&&son[rt].r==r) { son[rt].value+=w*(r-l+1); son[rt].nv+=w; return; } if(son[rt].nv) { son[rt<<1].nv+=son[rt].nv; son[rt<<1|1].nv+=son[rt].nv; son[rt<<1].value+=(son[rt<<1].r-son[rt<<1].l+1)*son[rt].nv; son[rt<<1|1].value+=(son[rt<<1|1].r-son[rt<<1|1].l+1)*son[rt].nv; son[rt].nv=0; } int m=(son[rt].l+son[rt].r)/2; if(r<=m) Update_n(w,l,r,rt<<1); else if(l>m) Update_n(w,l,r,rt<<1|1); else { Update_n(w,lson); Update_n(w,rson); } PushUp(rt); } ll Query(int l,int r,int rt) { if(son[rt].l==l&&son[rt].r==r) { return son[rt].value; } if(son[rt].nv) { son[rt<<1].nv+=son[rt].nv; son[rt<<1|1].nv+=son[rt].nv; son[rt<<1].value+=(son[rt<<1].r-son[rt<<1].l+1)*son[rt].nv; son[rt<<1|1].value+=(son[rt<<1|1].r-son[rt<<1|1].l+1)*son[rt].nv; son[rt].nv=0; } ll ret=0; int m=(son[rt].l+son[rt].r)/2; if(r<=m) ret=Query(l,r,rt<<1); else if(l>m) ret=Query(l,r,rt<<1|1); else { ret=Query(lson); ret+=Query(rson); } //PushUp(rt); return ret; } int main() { int n,m,l,r; ll w; char s[4]; while(scanf("%d%d",&n,&m)!=EOF) { Build(1,n,1); for(int i=1; i<=m; i++) { scanf("%s",s); if(s[0]=='C') { scanf("%d%d%I64d",&l,&r,&w); Update_n(w,l,r,1); } else { scanf("%d%d",&l,&r); printf("%I64d\n",Query(l,r,1)); } } } return 0; } /* 作为初学者,写起程序也总是会出现一些小毛病,都是对于线段树的理解不深造成的。 说一下这道题目需要注意的地方,那就是无论是每个节点的值还是增量,都要使用long long, 否则会错掉。 经过这段时间的学习,弄懂了线段树的好多地方,现在感觉做题也没那么费力了,都是简单题目, 对于初学者来说还是比较好的,欢迎大家一起讨论学习。 */
poj 3468 A Simple Problem with Integers(线段树),布布扣,bubuko.com
poj 3468 A Simple Problem with Integers(线段树)
标签:des style color 使用 os io strong for
原文地址:http://blog.csdn.net/knight_kaka/article/details/38581923