线段树专辑—— pku 3468 A Simple Problem with Integers
2011-11-09 21:28
399 查看
http://poj.org/problem?id=3468
典型的一道基于lazy传递的线段树题目,这题和一般题目不同的地方在于,它的每次操作不是简单的覆盖线段,而是累加。记得第一次写的时候纠结了好久。
好的,既然是累加,那么如何传递lazy呢?答案是传递累加值!
为线段树加一个add域,表示该线段需要加几。如果某区间的add不为0,那么就将该区间的add传递给其子区间,并且跟新子区间的sum_val值。
解这题最关键的就是要能够分清楚啥东西要传递,传递下去将有什么影响,其他的都好说!整体来说还是蛮轻松的
View Code
典型的一道基于lazy传递的线段树题目,这题和一般题目不同的地方在于,它的每次操作不是简单的覆盖线段,而是累加。记得第一次写的时候纠结了好久。
好的,既然是累加,那么如何传递lazy呢?答案是传递累加值!
为线段树加一个add域,表示该线段需要加几。如果某区间的add不为0,那么就将该区间的add传递给其子区间,并且跟新子区间的sum_val值。
解这题最关键的就是要能够分清楚啥东西要传递,传递下去将有什么影响,其他的都好说!整体来说还是蛮轻松的
View Code
#include<iostream> #include<string> #include<algorithm> using namespace std; struct node { int l; int r; __int64 add; __int64 sum_val; }; node tree[500000]; int n,m; __int64 num[100001]; void build(int i,int l,int r) { tree[i].l=l; tree[i].r=r; tree[i].add=0; if(l==r) { tree[i].sum_val=num[l]; return; } int mid=(l+r)/2; build(2*i,l,mid); build(2*i+1,mid+1,r); tree[i].sum_val=tree[2*i].sum_val+tree[2*i+1].sum_val; } void updata(int i,int l,int r,__int64 w) { if(tree[i].l>r || tree[i].r<l) return; if(tree[i].l>=l && tree[i].r<=r) { tree[i].add+=w; //注意是+=,因为这不是简单的覆盖 tree[i].sum_val+=(tree[i].r-tree[i].l+1)*w; //由于区间所有的值都需要加上w,那么自然整段区间就是加上(w*区间大小)了 return; } if(tree[i].add!=0) { tree[2*i].add+=tree[i].add; //同上,注意是+= tree[2*i+1].add+=tree[i].add; tree[2*i].sum_val+=(tree[2*i].r-tree[2*i].l+1)*tree[i].add; tree[2*i+1].sum_val+=(tree[2*i+1].r-tree[2*i+1].l+1)*tree[i].add; tree[i].add=0; } updata(2*i,l,r,w); updata(2*i+1,l,r,w); tree[i].sum_val=tree[2*i].sum_val+tree[2*i+1].sum_val; //回溯跟新 } __int64 ans; void find(int i,int l,int r) { if(tree[i].l>r || tree[i].r<l) return; if(tree[i].l>=l && tree[i].r<=r) { ans+=tree[i].sum_val; return; } if(tree[i].add!=0) { tree[2*i].add+=tree[i].add; tree[2*i+1].add+=tree[i].add; tree[2*i].sum_val+=(tree[2*i].r-tree[2*i].l+1)*tree[i].add; tree[2*i+1].sum_val+=(tree[2*i+1].r-tree[2*i+1].l+1)*tree[i].add; tree[i].add=0; } find(2*i,l,r); find(2*i+1,l,r); } int main() { int i,a,b; __int64 w; char c; freopen("in.txt","r",stdin); while(scanf("%d%d",&n,&m)==2) { for(i=1;i<=n;i++) { scanf("%I64d",&num[i]); } build(1,1,n); for(i=0;i<m;i++) { getchar(); scanf("%c",&c); if(c=='Q') { scanf("%d%d",&a,&b); ans=0; find(1,a,b); printf("%I64d\n",ans); } else { scanf("%d%d%I64d",&a,&b,&w); updata(1,a,b,w); } } } return 0; }
相关文章推荐
- pku 3468 A Simple Problem with Integers(线段树)
- 线段树 区域覆盖模版题 pku 3468 A Simple Problem with Integers 线段树——成段操作
- [PKU] 3468 A Simple Problem with Integers -- 线段树
- 【分块】【线段树】bzoj3212 Pku3468 A Simple Problem with Integers
- bzoj 3212: Pku3468 A Simple Problem with Integers (线段树)
- pku -- 3468 A Simple Problem with Integers(线段树)
- 线段树系列-pku-3468-A Simple Problem with Integers-区间修改区间求和
- POJ 3468 A Simple Problem with Integers(段更新的区间求和&Lazy思想&线段树)
- poj 3468 A Simple Problem with Integers(线段树区间更新)
- poj 3468 A Simple Problem with Integers 【线段树-成段更新】
- POJ---3468-A Simple Problem with Integers(线段树)
- POJ 3468 A Simple Problem with Integers (线段树)
- poj 3468 A Simple Problem with Integers(线段树——区间更新)
- 线段树_poj_3468_A Simple Problem with Integers
- POJ 3468 A Simple Problem with Integers (线段树 区间增减 区间求和)
- poj 3468 A Simple Problem with Integers 线段树 成段更新
- POJ 3468-A Simple Problem with Integers(线段树:成段更新,区间求和)
- [POJ 3468] A Simple Problem with Integers [线段树]
- poj 3468 A Simple Problem with Integers 基础线段树
- POJ 3468 A Simple Problem with Integers(线段树、lazy思想)