首页 > 代码库 > poj 3468 整理一下线段树的写法

poj 3468 整理一下线段树的写法

// 对于延迟更新,我们在updata 和query的时候 pushdown和pushup两个东西都要存在 

#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; typedef long long ll; struct node { ll l,r,sum,add; } tree[10000*4]; ll a[100001]; //ll x,y; void pushup(int id) { tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; } void build(ll l,ll r,int id) { if(l==r) { tree[id].sum=a[l]; return; } tree[id].l=l; tree[id].r=r; tree[id].add=0; ll mid=(l+r)/2; build(l,mid,id*2); build(mid+1,r,id*2+1); pushup(id); } void pushdown(int id) { if(tree[id].add) { tree[id*2].add +=tree[id].add; tree[id*2+1].add += tree[id].add; tree[id*2].sum += (tree[id*2].r-tree[id*2].l+1)*(tree[id*2].add); tree[id*2+1].sum += (tree[id*2+1].r-tree[id*2+1].l+1)*(tree[id*2+1].add); tree[id].add=0; } } void updata(ll x,ll y,ll l,ll r,int id,ll k) { if(x<=l && r<=y)// 在区间里面 就可以做一定操作 { tree[id].sum += (r-l+1)*k; tree[id].add += k; return; } pushdown(id);// ll mid=(l+r)/2; if(x <= mid) updata(x,y,l,mid,id*2,k); if(y > mid) updata(x,y,mid+1,r,id*2+1,k); pushup(id); } ll query(ll x,ll y,ll l,ll r,int id) { if(x<=l && r<=y) { return tree[id].sum; } pushdown(id); ll mid=(l+r)/2; ll sum=0; if(x<=mid) sum+=query(x,y,l,mid,id*2); if(y>mid) sum+=query(x,y,mid+1,r,id*2+1); pushup(id);// return sum; } int main() { int n,q; ll x,y,k; while(scanf("%d %d",&n,&q)!=EOF) { for(int i=1; i<=n; i++) { scanf("%d",&a[i]); } build(1,n,1); while(q--) { char s[3]; scanf("%s",s); if(s[0]==Q) { scanf("%lld %lld",&x,&y); printf("%lld\n",query(x,y,1,n,1)); } else if(s[0]==C) { scanf("%lld %lld %lld",&x,&y,&k); updata(x,y,1,n,1,k); } } } return 0; }

 

poj 3468 整理一下线段树的写法