• UVA-12436 Rip Van Winkle's Code (线段树区间更新)


    题目大意:一个数组,四种操作:

    long long data[250001];
    void A( int st, int nd ) {
        for( int i = st; i  <=  nd; i++ ) data[i] = data[i] + (i - st + 1);
    }
    void B( int st, int nd ) {
        for( int i = st; i  <=  nd; i++ ) data[i] = data[i] + (nd - i + 1);
    }
    void C( int st, int nd, int x ) {
        for( int i = st; i  <=  nd; i++ ) data[i] = x;
    }
    long long S( int st, int nd ) {
        long long res = 0;
        for( int i = st; i  <=  nd; i++ ) res += data[i];
        return res;
    }

    模拟这四种操作。

    题目分析:三种更新操作,一种询问操作。三种更新实际上是两种,add更新(等差数列做加减运算仍是等差数列)和set更新,add更新的懒标记记录首项、尾项和公差。

    代码如下:

    # include<bits/stdc++.h>
    using namespace std;
    # define LL long long
    # define mid (l+(r-l)/2)
    
    const int N=250000;
    
    struct Node
    {
        LL sum;
        LL x,d,st,ed;
        bool lazy_set;
        bool lazy_add;
    };
    Node tr[(N+5)*4+100];
    char op[2];
    
    void clear_lazy(int rt)
    {
        tr[rt].lazy_add=false;
        tr[rt].d=tr[rt].st=tr[rt].ed=0;
    }
    
    void change1(int rt,int l,int r,LL st,LL ed,LL d)
    {
        tr[rt].lazy_add=true;
        tr[rt].sum+=(LL)(r-l+1)*(st+ed)/2;
        tr[rt].st+=st;
        tr[rt].ed+=ed;
        tr[rt].d+=d;
    }
    
    void change2(int rt,int l,int r,LL x)
    {
        tr[rt].lazy_set=true;
        tr[rt].sum=(LL)(r-l+1)*x;
        tr[rt].x=x;
    
        clear_lazy(rt);
    }
    
    void pushUp(int rt)
    {
        tr[rt].sum=tr[rt<<1].sum+tr[rt<<1|1].sum;
    }
    
    void pushDown(int rt,int l,int r)
    {
        if(tr[rt].lazy_set){
    
            change2(rt<<1,l,mid,tr[rt].x);
            change2(rt<<1|1,mid+1,r,tr[rt].x);
            tr[rt].lazy_set=false;
        }
        if(tr[rt].lazy_add){
    
            LL st=tr[rt].st;
            LL ed=tr[rt].ed;
            int d=tr[rt].d;
    
            change1(rt<<1,l,mid,st,st+d*(mid-l),d);
            change1(rt<<1|1,mid+1,r,st+d*(mid-l+1),ed,d);
    
            clear_lazy(rt);
        }
    }
    
    void build(int rt,int l,int r)
    {
        tr[rt].lazy_set=false;
        tr[rt].lazy_add=false;
        tr[rt].sum=tr[rt].d=0;
        tr[rt].st=tr[rt].ed=0;
        if(l==r) return ;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
    }
    
    void update1(int rt,int l,int r,int L,int R,LL d)
    {
       if(L<=l&&r<=R){
            if(d>0){
                change1(rt,l,r,l-L+1,r-L+1,d);
            }else{
                change1(rt,l,r,R-l+1,R-r+1,d);
            }
       }else{
            pushDown(rt,l,r);
            if(L<=mid) update1(rt<<1,l,mid,L,R,d);
            if(R>mid) update1(rt<<1|1,mid+1,r,L,R,d);
            pushUp(rt);
       }
    }
    
    void update2(int rt,int l,int r,LL L,LL R,LL x)
    {
       if(L<=l&&r<=R){
            change2(rt,l,r,x);
       }else{
           pushDown(rt,l,r);
           if(L<=mid) update2(rt<<1,l,mid,L,R,x);
           if(R>mid) update2(rt<<1|1,mid+1,r,L,R,x);
           pushUp(rt);
       }
    }
    
    LL query(int rt,int l,int r,LL L,LL R)
    {
        if(L<=l&&r<=R) return tr[rt].sum;
        pushDown(rt,l,r);
        LL res=0;
        if(L<=mid) res+=query(rt<<1,l,mid,L,R);
        if(R>mid) res+=query(rt<<1|1,mid+1,r,L,R);
        return res;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            build(1,1,N);
            LL a,b,c;
            while(n--)
            {
                scanf("%s",op);
                if(op[0]=='A'){
                    scanf("%lld%lld",&a,&b);
                    update1(1,1,N,a,b,1ll);
                }else if(op[0]=='B'){
                    scanf("%lld%lld",&a,&b);
                    update1(1,1,N,a,b,-1ll);
                }else if(op[0]=='C'){
                    scanf("%lld%lld%lld",&a,&b,&c);
                    update2(1,1,N,a,b,c);
                }else{
                    scanf("%lld%lld",&a,&b);
                    printf("%lld
    ",query(1,1,N,a,b));
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    DTD与shema学习
    xml基本语法学习
    快速写出main方法和system.out.print()
    Eclipse常见快捷键
    System.out.print()与toString()
    HttpURLConnection学习
    如何查看开关机时间
    阿里云云服务器硬盘分区及挂载
    java环境搭建
    使用jstack 发现死锁
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5593235.html
Copyright © 2020-2023  润新知