首页 > 代码库 > 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 整理一下线段树的写法
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。