Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 73239 | Accepted: 22607 | |
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
Source
#include<iostream> #include<sstream> #include<algorithm> #include<cstdio> #include<string.h> #include<cctype> #include<string> #include<cmath> #include<vector> #include<stack> #include<queue> #include<map> #include<set> using namespace std; const int INF=100003; int val[INF]; struct Tree { int left,right; long long total,mark; } tree[INF<<2]; long long create(int root ,int left,int right) { tree[root].left=left; tree[root].right=right; tree[root].mark=0; if(left==right) return tree[root].total=val[left]; long long a,b,mid=(left+right)>>1; a=create(root<<1,left,mid); b=create(root<<1|1,mid+1,right); return tree[root].total=a+b; } void update_mark(int root) { if(tree[root].mark) { tree[root].total+=tree[root].mark*(tree[root].right-tree[root].left+1); if(tree[root].left!=tree[root].right) { tree[root<<1].mark+=tree[root].mark; tree[root<<1|1].mark+=tree[root].mark; } tree[root].mark=0; } } long long calculate(int root ,int left,int right) { update_mark(root); if(tree[root].left>right||tree[root].right<left) return 0; if(tree[root].left>=left&&tree[root].right<=right) { return tree[root].total; } long long a=calculate(root<<1,left,right); long long b=calculate(root<<1|1,left,right); return a+b; } long long update(int root , int left,int right,int val) { update_mark(root); if(tree[root].left>right||tree[root].right<left) return tree[root].total; if(tree[root].left>=left&&tree[root].right<=right) { tree[root].mark+=val;//这里一点需要注意,应重新更新root结点 update_mark(root); //让其返回当前结点更新后的最新信息。 return tree[root].total; } long long a=update(root<<1,left,right,val); long long b=update(root<<1|1,left,right,val); return tree[root].total=a+b; } int main() { int n,q; while(cin>>n>>q) { for(int i=1; i<=n; i++) scanf("%d",&val[i]); create(1,1,n); for(int i=0; i<q; i++) { getchar(); char ch; int a,b,c; scanf("%c",&ch); switch(ch) { case 'Q': scanf("%d%d",&a,&b); printf("%lld\n",calculate(1,a,b)); break; case 'C': scanf("%d%d%d",&a,&b,&c); update(1,a,b,c); break; } } } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
Poj 3468 A Simple Problem with Integers(线段树 区间更新 延迟标记)
原文地址:http://blog.csdn.net/lsgqjh/article/details/46793001