poj3468 线段树成段更新水题
2016-08-31 20:50
239 查看
poj 3468 A Simple Problem with Integers
题目:
ou 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.
题意:
就是给一个比较长的序列和两种操作,Q时询问区间所有的数字之和,C是给区间上的所有数字都加上某一个数字。思路:
看上去就是一道线段树的成段更新,说到成段更新就一定要会打lazy标记,lazy标记的作用就是,当update操作到的某一个节点p表示的区间[l,r]完全在操作范围[x,y]内时,就不用继续操作p的子节点,直接把tree[p]+=(r-l+1)*num,lazy[p]+=num;就想当于标记好这个区间内数字的都应该加上lazy[p]的数值,就可以返回了。然后是考虑什么时候要把lazy标记下方,就是对于当update操作,或是query操作到一点p是,发现[l,r]并不完全被[x,y]包含,这时就要继续操作他们的子节点,在操作之前就应该下方lazy标记,然后把lazy[p]清空即可,记得update操作最后要更新tree[p]=tree[p<<1]+tree[p<<1|1];
代码:
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #define N 101000 using namespace std; typedef long long ll; ll tree[N<<2]; ll lazy[N<<2]; ll n,m; void build(ll p,ll l,ll r) { if(l==r) { scanf("%I64d",&tree[p]); return; } ll mid=(l+r)>>1; build(p<<1,l,mid); build((p<<1)|1,mid+1,r); tree[p]=tree[p<<1]+tree[(p<<1)|1]; } void pushdown(ll p,ll m) { if(lazy[p]) { lazy[p<<1]+=lazy[p]; lazy[p<<1|1]+=lazy[p]; tree[p<<1]+=lazy[p]*(m-(m>>1)); tree[p<<1|1]+=lazy[p]*(m>>1); lazy[p]=0; } } void update(ll p,ll l,ll r,ll x,ll y,ll val) { if(x<=l&&r<=y) { lazy[p]+=val; tree[p]+=val*(r-l+1); return ; } pushdown(p,r-l+1); ll mid=(l+r)>>1; if(x<=mid) update(p<<1,l,mid,x,y,val); if(y>=mid+1) update( (p<<1)|1,mid+1,r,x,y,val); tree[p]=tree[p<<1]+tree[p<<1|1]; } ll query(ll p,ll l,ll r,ll x,ll y) { if(x<=l&&r<=y) return tree[p]; pushdown(p,r-l+1); ll mid=(l+r)>>1; ll tmp=0; if(x<=mid) tmp+=query(p<<1,l,mid,x,y); if(y>=1+mid) tmp+=query((p<<1)|1,mid+1,r,x,y); return tmp; } int main() { scanf("%I64d%I64d",&n,&m); memset(tree,0,sizeof(tree)); memset(lazy,0,sizeof(lazy)); build(1,1,n); ll x,y,z; for(ll i=1;i<=m;i++) { char s[6]; scanf("%s",s); if(s[0]=='Q') { scanf("%I64d%I64d",&x,&y); ll ans=query(1,1,n,x,y); printf("%I64d\n",ans); } else { scanf("%I64d%I64d%I64d",&x,&y,&z); update(1,1,n,x,y,z); } } return 0; }
相关文章推荐
- Poj3468 线段树 -- 成段更新
- poj3468 A Simple Problem with Integers(线段树成段更新)
- 线段树成段更新操作及Lazy思想(POJ3468解题报告)
- HDU.1698 屠夫(线段树成段更新大大大水题)
- 【POJ3468】【线段树成段更新】
- poj3468_A Simple Problem with Integers_线段树_成段更新求和
- POJ3468-A Simple Problem with Integers(线段树 成段更新求和)
- HDU.1698 屠夫(线段树成段更新大大大水题)
- poj3468 线段树成段更新模板
- poj3468(线段树成段更新)
- 线段树成段更新1002 POJ3468
- hdu1556 Color the ball 线段树,成段更新水题
- POJ3468 A Simple Problem with Integers(线段树成段更新,区间查询)
- poj3468 A Simple Problem with Integers[线段树成段更新成段查询]
- poj3468 A Simple Problem with Integers 线段树,成段更新
- POJ3468_A Simple Problem with Integers(线段树/成段更新)
- 线段树成段更新裸题POJ3468
- hdu1698Just a Hook 线段树 成段更新水题
- 线段树成段更新裸题POJ3468
- POJ3468 A Simple Problem with Integers 【线段树】+【成段更新】