POJ 3468——A Simple Problem with Integers——————【线段树区间更新, 区间查询】
A Simple Problem with Integers
Time Limit: 5000MS | Memory Limit: 131072K | |
Total Submissions: 86780 | Accepted: 26950 | |
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
The sums may exceed the range of 32-bit integers.
Source
POJ Monthly--2007.11.25, Yang Yi
题目大意:给你n个数,m次询问。询问包括为区间内每个值增加c以及查询区间内所有值的和。
解题思路:延迟标记。保证当前值的正确性。lazy不能清空,应该累积,因为可能上次的lazy还没有向下推。
#include<stdio.h> #include<vector> #include<queue> #include<string.h> #include<algorithm> using namespace std; typedef long long LL; const int maxn = 1e6+20; const int INF = 0x3f3f3f3f; const int mod = 1e9+7; #define mid (L+R)/2 #define lson rt*2,L,mid #define rson rt*2+1,mid+1,R struct SegTree{ LL val, lazy; }segs[maxn*4]; void PushUp(int rt){ segs[rt].val = segs[rt*2+1].val + segs[rt*2].val; } void PushDown(int rt,int L,int R){ if(segs[rt].lazy){ segs[rt*2].val += segs[rt].lazy*(mid-L +1); //保证当前的正确性 segs[rt*2+1].val += segs[rt].lazy*(R-mid); segs[rt*2].lazy += segs[rt].lazy; //累积 segs[rt*2+1].lazy += segs[rt].lazy; segs[rt].lazy = 0; } } void buildtree(int rt,int L,int R){ segs[rt].val = 0; segs[rt].lazy = 0; if(L == R){ scanf("%lld",&segs[rt].val); return ; } buildtree(lson); buildtree(rson); PushUp(rt); } //void Update(int rt,int L,int R,int _idx,int _val){ // if(L == R && L == _idx){ // segs[rt].val += _val; // return ; // } // if(_idx <= mid) // Update(lson,_idx,_val); // else // Update(rson,_idx,_val); // PushUp(rt); //} LL query(int rt,int L,int R,int l_ran,int r_ran){ if(l_ran <= L&&R <= r_ran){ return segs[rt].val; } PushDown(rt,L,R); LL ret = 0; if(l_ran <= mid){ ret += query(lson,l_ran,r_ran); } if(r_ran > mid){ ret += query(rson,l_ran,r_ran); } PushUp(rt); return ret; } void Update(int rt,int L,int R,int l_ran,int r_ran,LL chg){ if(l_ran <= L&&R <= r_ran){ segs[rt].val += chg*(R-L+1); segs[rt].lazy += chg; return ; } PushDown(rt,L,R); if(l_ran <= mid) Update(lson,l_ran,r_ran,chg); if(r_ran > mid) Update(rson,l_ran,r_ran,chg); PushUp(rt); } int main(){ int n,m; while(scanf("%d%d",&n,&m)!=EOF){ buildtree(1,1,n); int l,r; LL c; char s[12]; for(int i = 1; i <= m; i++){ scanf("%s",s); if(s[0]=='Q'){ scanf("%d%d",&l,&r); LL ans = query(1,1,n,l,r); printf("%lld\n",ans); }else{ scanf("%d%d%lld",&l,&r,&c); Update(1,1,n,l,r,c); } } } return 0; }
学学学 练练练 刷刷刷