POJ -- 3468 --线段树成段更新
2013-08-21 21:24
239 查看
很久以前的题目再做一遍复习一下。
要点:
1)约定在任何时候 add_num 到达节点的时候就立即更新节点的 sum 值。
2)每次更新节点回溯的时候记得维护节点的 sum 值。
3)执行询问操作的时候,遇到 lazy 标记为1 的时候往下 Push_down,,同时记得第一点
4)遇到符合要求的询问区间时,由于第一条的规定,直接返回 sum 值,而不必加上 区间长度*add_num
好了,以前由于不知道什么时候返回sun 值 和 什么时候加上 区间长度*add_num犯糊涂,加上了第一条的约定,这样就比较明朗了
要点:
1)约定在任何时候 add_num 到达节点的时候就立即更新节点的 sum 值。
2)每次更新节点回溯的时候记得维护节点的 sum 值。
3)执行询问操作的时候,遇到 lazy 标记为1 的时候往下 Push_down,,同时记得第一点
4)遇到符合要求的询问区间时,由于第一条的规定,直接返回 sum 值,而不必加上 区间长度*add_num
好了,以前由于不知道什么时候返回sun 值 和 什么时候加上 区间长度*add_num犯糊涂,加上了第一条的约定,这样就比较明朗了
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<map> #include<cstdlib> using namespace std; typedef long long LL; const int MAXN = 100020; struct node { int l,r; bool lazy; LL add; LL sum; }p[MAXN<<2]; int a[MAXN]; int n,m; bool init() { if(scanf("%d%d",&n,&m)==EOF)return false; for(int i=1;i<=n;i++)scanf("%d",a+i); return true; } void build(int ic,int l,int r) { p[ic].l=l; p[ic].r=r; p[ic].lazy=0; if(l==r) { p[ic].sum=a[l]; return; } int mid = (l+r)>>1; build(ic<<1,l,mid); build(ic<<1|1,mid+1,r); p[ic].sum=p[ic<<1].sum+p[ic<<1|1].sum; } void push_down(int ic) { int l = p[ic].l; int r = p[ic].r; int lc = ic<<1,rc=ic<<1|1; p[lc].add+=p[ic].add; p[rc].add+=p[ic].add; p[lc].sum += (p[lc].r-p[lc].l+1)*p[ic].add; p[rc].sum += (p[rc].r-p[rc].l+1)*p[ic].add; p[ic].sum = p[lc].sum+p[rc].sum; p[lc].lazy=p[rc].lazy =1; p[ic].add = 0; p[ic].lazy =0 ; } void update(int ic,int l_up,int r_up,int add_num) { int l = p[ic].l; int r = p[ic].r; //printf("ic:%d l:%d r:%d l_up:%d r_up:%d\n",ic,l,r,l_up,r_up); if((l==l_up)&&(r==r_up)) { p[ic].lazy = 1; p[ic].add +=add_num; p[ic].sum +=(r-l+1)*add_num; // printf("return %d \n",ic); return; } if(p[ic].lazy)push_down(ic); int mid = (l+r)>>1; if(l_up>mid)update(ic<<1|1,l_up,r_up,add_num); else if(r_up<=mid)update(ic<<1,l_up,r_up,add_num); else { update(ic<<1,l_up,mid,add_num); update(ic<<1|1,mid+1,r_up,add_num); } int lc = ic<<1; int rc = ic<<1|1; p[ic].sum=p[lc].sum+p[rc].sum; } void ADD() { int x,y; int add_num; scanf("%d%d%d",&x,&y,&add_num); if(x>y)swap(x,y); update(1,x,y,add_num); } LL do_Query(int ic,int Ql,int Qr) { int l = p[ic].l; int r = p[ic].r; if(l==Ql&&r==Qr) { return p[ic].sum; } if(p[ic].lazy)push_down(ic); int mid = (l+r)>>1; if(Qr<=mid)return do_Query(ic<<1,Ql,Qr); else if(mid<Ql)return do_Query(ic<<1|1,Ql,Qr); else { return do_Query(ic<<1,Ql,mid)+do_Query(ic<<1|1,mid+1,Qr); } } void Query() { int x,y; scanf("%d%d",&x,&y); printf("%lld\n",do_Query(1,x,y)); } void op_Tree(int ic) { int l = p[ic].l; int r = p[ic].r; printf("ic:%d l:%d r:%d sum:%I64d\n",ic,l,r,p[ic].sum); if(l==r)return; op_Tree(ic<<1); op_Tree(ic<<1|1); } #define dbug9 void debug() { op_Tree(1); } void solve() { char cmd[10]; memset(p,0,sizeof(p)); build(1,1,n); #ifdef dbug debug(); #endif while(m--) { scanf("%s",cmd); switch(cmd[0]) { case 'C':ADD();break; case 'Q':Query();break; default :cout<<"fuck!"<<endl; } } } int main() { freopen("3468.txt","r",stdin); while(init()) solve(); return 0; }
相关文章推荐
- poj 3468 -- A Simple Problem with Integers ( 线段树 , 段更新 , 段求和 )
- POJ - 3468 - A Simple Problem with Integers (线段树 - 成段更新)
- POJ3468——线段树成段更新——A Simple Problem with Integers
- [ACM] poj 3468 A Simple Problem with Integers(线段树,成段更新,懒惰标记)
- POJ 3468 A Simple Problem with Integers(线段树成段更新)
- poj 3468 A Simple Problem with Integers(线段树成段更新,延迟标记,Lazy)
- poj_3468线段树成段更新求区间和
- poj 3468 线段树成段更新
- poj 3468 A Simple Problem with Integers 线段树 成段更新
- POJ 3468 【线段树区间更新-成段更新】
- [ACM] poj 3468 A Simple Problem with Integers(线段树,成段更新,懒惰标记)
- POJ 3468 A Simple Problem with Integers 线段树成段更新+区间查询
- POJ 3468 A Simple Problem with Integers(线段树成段更新)
- poj_3468线段树成段更新求区间和
- poj 3468 线段树--成段更新
- [ACM] 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,线段树成段更新