标签:线段树
区间更新和查询
区间更新要延迟更新,就是当某结点完全处于要更新的区间之中时,我们只更新到该结点,并把其子结点要更新的值记录在本结点,当要向下更新或查询时再进行更新
#include<stdio.h> #include<string.h> //typedef long long ll; typedef __int64 ll; #define N 100005 struct Node{ int l,r; ll sum,add; }t[N*4]; void build(int cur,int l,int r){ t[cur].l=l; t[cur].r=r; t[cur].sum=0; t[cur].add=0; if(l==r) return; int mid=(l+r)>>1; build(cur*2,l,mid); build(cur*2+1,mid+1,r); } void pushdown(int cur){ t[cur*2].sum+=(t[cur*2].r-t[cur*2].l+1)*t[cur].add; t[cur*2+1].sum+=(t[cur*2+1].r-t[cur*2+1].l+1)*t[cur].add; t[cur*2].add+=t[cur].add; t[cur*2+1].add+=t[cur].add; t[cur].add=0; } void pushup(int cur){ t[cur].sum=t[cur*2].sum+t[cur*2+1].sum; } void update(int cur,int l,int r,ll num){ if(t[cur].r<l||t[cur].l>r) return; if(t[cur].l>=l && r>=t[cur].r){ t[cur].sum+=(t[cur].r-t[cur].l+1)*num; t[cur].add+=num; //printf("%I64d\n",t[cur].sum); return; } pushdown(cur); int mid=(l+r)>>1; update(cur*2,l,r,num); update(cur*2+1,l,r,num); pushup(cur); } ll query(int cur,int l,int r){ if(t[cur].r<l||t[cur].l>r) return 0; if(l<=t[cur].l&&t[cur].r<=r) { return t[cur].sum; } pushdown(cur); return query(cur*2,l,r)+query(cur*2+1,l,r); } int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int n,q; scanf("%d%d",&n,&q); int tmp,i; build(1,1,n); for(i=1;i<=n;i++){ scanf("%d",&tmp); update(1,i,i,tmp); } //printf("%I64d\n",t[1].sum); char c[10];//为了防止有接收空格的情况出现,用数组接收 for(i=0;i<q;i++){ scanf("%s",c); int tmp1,tmp2,tmp3; //printf("%s\n",c); if(c[0]=='Q'){ scanf("%d%d",&tmp1,&tmp2); printf("%I64d\n",query(1,tmp1,tmp2)); } else { scanf("%d%d%d",&tmp1,&tmp2,&tmp3); update(1,tmp1,tmp2,tmp3); } } return 0; }
POJ 3468 A Simple Problem with Integers
标签:线段树
原文地址:http://blog.csdn.net/lj94093/article/details/45747741