poj3468 A Simple Problem with Integers (线段树的懒惰标记)

xiaoxiao2021-02-28  101

题目链接:

http://poj.org/problem?id=3468

题意:

对于一个区间的数有两种操作:

C a b c 在区间[a,b]内的数全部加上c

Q a b   查询区间[a,b]之间的数的和 

解:

嗯,没什么好说的,就直接线段树就行了,需要注意的就是懒惰标记的理解和应用了。

关于懒惰标记的理解推荐这篇博客:http://blog.csdn.net/sdjzping/article/details/19542103

代码:

#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int maxn=1e5+50; typedef long long ll; ll a[maxn];int n; struct Tree{ int node,l,r; ll v,laz; }seg[ maxn << 2 ]; void pushup(int node){ seg[node].v=seg[node<<1].v+seg[node<<1|1].v; } void pushdown(int node,int b){ if(seg[node].laz) { seg[node<<1].laz+=seg[node].laz; seg[node<<1|1].laz+=seg[node].laz; seg[node<<1].v+=(ll)(b-(b/2))*seg[node].laz; seg[node<<1|1].v+=(ll)(b/2)*seg[node].laz; seg[node].laz=0; } } void build(int l,int r,int node){ seg[node].l=l;seg[node].r=r;seg[node].laz=0; if(l==r){ seg[node].v=a[l]; return ; } int mid=(l+r)/2; build(l,mid,node<<1); build(mid+1,r,node<<1|1); pushup(node); } void update(int l,int r,int node,int k){ if(l<=seg[node].l&&seg[node].r<=r) { seg[node].v+=(seg[node].r-seg[node].l+1)*k; seg[node].laz+=k; return ; } pushdown(node,seg[node].r-seg[node].l+1); int mid=(seg[node].l+seg[node].r)/2; if(mid>=l) update(l,r,node<<1,k); if(r>mid) update(l,r,node<<1|1,k); pushup(node); } ll query(int l,int r,int node){ if(l<=seg[node].l&&seg[node].r<=r) { //cout<<"Node:"<<node<<" L:"<<seg[node].l<<" R:"<<seg[node].r<<endl; return seg[node].v; } pushdown(node,seg[node].r-seg[node].l+1); int mid=(seg[node].l+seg[node].r)/2; ll xa=0,xb=0; if(mid>=l) xa=query(l,r,node<<1); if(r>mid) xb=query(l,r,node<<1|1); pushup(node); //cout<<"Node:"<<node<<" Xa:"<<xa<<" Xb:"<<xb<<endl; return xa+xb; } void show(int node){ cout<<"Node:"<<node<<endl; cout<<"L:"<<seg[node].l<<" R:"<<seg[node].r<<endl; cout<<"Value:"<<seg[node].v<<endl; cout<<endl; if(seg[node].l==seg[node].r)return ; show(node<<1); show(node<<1|1); } int main() { int n,q; while(~scanf("%d%d",&n,&q)) { for(int i=1;i<=n;i++) scanf("%I64d",&a[i]); build(1,n,1); while(q--){ char op[2]; int c1,c2; scanf("%s",op); if(op[0]=='C') { int c3; scanf("%d%d%d",&c1,&c2,&c3); update(c1,c2,1,c3); //show(1); } else { scanf("%d%d",&c1,&c2); ll ans=query(c1,c2,1); printf("%I64d\n",ans); } } } return 0; }

转载请注明原文地址: https://www.6miu.com/read-94948.html

最新回复(0)