码迷,mamicode.com
首页 > 其他好文 > 详细

POJ-3468 A Simple Problem with Integers

时间:2017-04-29 23:31:39      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:nbsp   标记   with   return   模板   tle   sum   区间更新   name   

线段树的模板题吧!区间更新,,,,也可以单点更新,不过会TLE,,,

区间更新的关键在于lazy标记,,,,

如果要更新的区间包括当前的区间的话,就加一个lazy标记,更新整个区间的值,并且停止,

当再次更新到这个区间的时候,就把这个lazy标记pushdown//更新左子树和右子树,同时消除lazy标记,,

# include <cstdio>
# include <iostream>
# include <cstring>
# include <algorithm>
using namespace std;

const int maxn=1e5+5;
long long int sum[maxn*4],seg[maxn*4];

void pushup(int rt){
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    return ;
}

void pushdown(int l,int r,int rt){
    int mid=(l+r)>>1;
        seg[rt<<1]+=seg[rt];
        sum[rt<<1]+=(mid-l+1)*seg[rt];
        seg[rt<<1|1]+=seg[rt];
        sum[rt<<1|1]+=(r-mid)*seg[rt];
        seg[rt]=0;
}

void build(int l,int r,int rt){
    seg[rt]=0;
    if(l==r) {
        scanf("%lld",&sum[rt]);
        return ;
    }
    int mid=(l+r)>>1;
    build(l,mid,rt<<1);
    build(mid+1,r,rt<<1|1);
    pushup(rt);
}

void update(int L,long long int R,int l,int r,int rt,int c){
    if(L<=l&&r<=R) {
        seg[rt]+=c;
        sum[rt]+=(r-l+1)*c;
        return ;
    }
    if(seg[rt]) pushdown(l,r,rt);
    int mid=(l+r)>>1;
    if(L<=mid) update(L,R,l,mid,rt<<1,c);
    if(mid<R) update(L,R,mid+1,r,rt<<1|1,c);
    pushup(rt);
}

long long int query(int L,int R,int l,int r,int rt){
    if(L<=l&&r<=R){
        return sum[rt];
    }
    if(seg[rt]) pushdown(l,r,rt);
    int mid=(l+r)>>1;
    long long int ans=0;
    if(L<=mid) ans+=query(L,R,l,mid,rt<<1);
    if(mid<R) ans+=query(L,R,mid+1,r,rt<<1|1);
    pushup(rt);
    return ans;
}

int main(){
    long long int n,q;
    while(scanf("%lld%lld",&n,&q)==2&&n&&q){
        build(1,n,1);
        char s[5];
        long long int a,b;
        int c;
        for(long long int i=0;i<q;i++){
            scanf("%s",s);
            if(s[0]==‘Q‘){
                scanf("%lld%lld",&a,&b);
                printf("%lld\n",query(a,b,1,n,1));
            }
            if(s[0]==‘C‘){
                scanf("%lld%lld%d",&a,&b,&c);
                update(a,b,1,n,1,c);
            }
        }
    }
    return 0;
}

POJ-3468 A Simple Problem with Integers

标签:nbsp   标记   with   return   模板   tle   sum   区间更新   name   

原文地址:http://www.cnblogs.com/lintanxi/p/6786506.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!