• HDU 3468 A Simple Problem with Integers


    题目来源:http://poj.org/problem?id=3468

    这是线段树的区间更新,用单点更新会超时

    #include <iostream>
    #include <cstdio>
    using namespace std;
    
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define ll long long
    
    const int maxn=100010;
    ll sum[maxn<<2],lazy[maxn<<2];
    
    void putup(int rt){
        sum[rt]=sum[rt<<1]+sum[rt<<1|1];
    }
    void putdown(int rt,int m){
        if(lazy[rt]){
            lazy[rt<<1]+=lazy[rt];
            lazy[rt<<1|1]+=lazy[rt];
            sum[rt<<1]+=lazy[rt]*(m-(m>>1));
            sum[rt<<1|1]+=lazy[rt]*(m>>1);
            lazy[rt]=0;
        }
    }
    
    void build(int l,int r,int rt){
        lazy[rt]=0;
        if(l==r){
            scanf("%lld",&sum[rt]);
            return;
        }
    
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        putup(rt);
    }
    
    //a,b代表更新的区间[a,b]
    //value代表区间[a,b]增加的值。
    //rt代表当前的根节点
    void update(int a,int b,int value,int l,int r,int rt){
    
        //[a,b]和[l,r]没有相交的方;
        if(a>r||b<l)
            return ;
    
        //[a,b]包含[l,r]的情况
        if(a<=l&&b>=r){
            lazy[rt]+=value;
            //注意这儿有个加号
            sum[rt]+=(ll)value*(r-l+1);
            return;
        }
    
        //[a,b]和[l,r]相交的情况
        putdown(rt,r-l+1);
        int m=(l+r)>>1;
        update(a,b,value,lson);
        update(a,b,value,rson);
        putup(rt);
    }
    
    
    ll query(int a,int b,int l,int r,int rt){
        //[a,b]和[l,r]没有相交的情况
        if(b<l||a>r) return 0;
        
        //把这行代码放在这儿会发生Runtime error
        //putdown(rt,r-l+1);
        //[a,b]包含[l,r]的情况
        if(a<=l&&b>=r)
            return sum[rt];
        
        putdown(rt,r-l+1);
        //[a,b]和[l,r]相交的情况
            int m=(l+r)>>1;
            ll vl=query(a,b,lson);
            ll vr=query(a,b,rson);
            return vl+vr;
        
    }
    int main(){
        int n,m;
        int a,b,c;
        char str[5];
    
        scanf("%d%d",&n,&m);
        build(1,n,1);
        while(m--){
            scanf("%s",str);
            if(str[0]=='Q'){
                scanf("%d%d",&a,&b);
                printf("%lld
    ",query(a,b,1,n,1));
            }else if(str[0]=='C'){
                scanf("%d%d%d",&a,&b,&c);
                update(a,b,c,1,n,1);
            }
        }
        return 0;
    }
    自己选的路,跪着也要把它走完------ACM坑
  • 相关阅读:
    餐饮点菜控件
    数据模块池
    关于sqlite数据库
    PHP使用DateTime类做时间日期到字符串转换
    php字符串比较函数
    Xdebug开源PHP程序调试器
    ubuntu chmod 无法更改 文件夹权限 系统提示“不允许的操作 2、linux 如何修改只读文件 3、ubuntu安装
    ubuntu的命令day1
    linux用终端上传文件和文件家到远程的服务器
    Symfony学习--原创。。。。
  • 原文地址:https://www.cnblogs.com/IKnowYou0/p/6402691.html
Copyright © 2020-2023  润新知