zoukankan      html  css  js  c++  java
  • hdu4348区间更新的主席树+标记永久化

    http://acm.hdu.edu.cn/showproblem.php?pid=4348

    sb的标记永久化即可,刚开始add和sum没复制过来wa了两发。。。,操作和原来的都一样,出来单点变成区间,还要加一个标记永久化,这样就不用pushdown新加节点而爆内存了

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    //#define ls l,m,rt<<1
    //#define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=100000+10,maxn=90000+10,inf=0x3f3f3f3f;
    
    int rt[N],tot,ls[N*30],rs[N*30];
    ll sum[N*30],add[N*30];
    void build(int &o,int l,int r)
    {
        o=++tot;
        add[o]=0;
        if(l==r)
        {
            scanf("%lld",&sum[o]);
            return ;
        }
        int m=(l+r)>>1;
        build(ls[o],l,m);
        build(rs[o],m+1,r);
        sum[o]=sum[ls[o]]+sum[rs[o]];
    //    printf("%d+++%d+++%d+++%lld+++%d
    ",l,r,o,sum[o],add[o]);
    }
    void update(int &o,int l,int r,int last,int L,int R,int x)
    {
        o=++tot;
        ls[o]=ls[last];
        rs[o]=rs[last];
        sum[o]=sum[last];
        add[o]=add[last];
        if(L<=l&&r<=R)
        {
            add[o]+=x;
            return ;
        }
        int m=(l+r)>>1;
        if(L<=m)update(ls[o],l,m,ls[last],L,R,x);
        if(m<R)update(rs[o],m+1,r,rs[last],L,R,x);
        sum[o]=sum[ls[o]]+add[ls[o]]*(m-l+1)+sum[rs[o]]+add[rs[o]]*(r-m);
    //    printf("%d %d %lld %lld
    ",ls[o],rs[o],sum[ls[o]],sum[rs[o]]);
    //    printf("%d+++%d+++%d+++%lld+++%d
    ",l,r,o,sum[o],add[o]);
    }
    ll query(int o,ll ad,int l,int r,int L,int R)
    {
    //    printf("%d %d %d %lld
    ",l,r,o,ad);
        if(L<=l&&r<=R)
            return (ad+add[o])*(r-l+1)+sum[o];
        ll ans=0;
        int m=(l+r)>>1;
        if(L<=m)ans+=query(ls[o],ad+add[o],l,m,L,R);
        if(m<R)ans+=query(rs[o],ad+add[o],m+1,r,L,R);
        return ans;
    }
    char s[10];
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&n,&m))
        {
            build(rt[0],1,n);
            int cnt=0;
            while(m--)
            {
                scanf("%s",s);
                if(s[0]=='Q')
                {
                    int l,r;
                    scanf("%d%d",&l,&r);
                    printf("%lld
    ",query(rt[cnt],0,1,n,l,r));
                }
                else if(s[0]=='C')
                {
                    cnt++;
                    int l,r,c;
                    scanf("%d%d%d",&l,&r,&c);
                    update(rt[cnt],1,n,rt[cnt-1],l,r,c);
                }
                else if(s[0]=='H')
                {
                    int l,r,c;
                    scanf("%d%d%d",&l,&r,&c);
                    printf("%lld
    ",query(rt[c],0,1,n,l,r));
                }
                else scanf("%d",&cnt);
            }
        }
        return 0;
    }
    /********************
    10 5
    1 2 3 4 5 6 7 8 9 10
    Q 2 4
    C 3 6 3
    Q 2 4
    ********************/
    View Code
  • 相关阅读:
    PAT Basic 1023 组个最小数 (20 分)
    PAT Advanced 1048 Find Coins (25 分)
    PAT Basic 1005 继续(3n+1)猜想 (25 分)
    PAT Advanced 1050 String Subtraction (20 分)
    PAT Advanced 1041 Be Unique (20 分)
    PAT Basic 1047 编程团体赛 (20 分)
    SpringSecurity整合SpringBoot
    给正在运行的Docker容器动态绑定卷组
    linux 中格式化json字符串
    docker/kubernetes国内源/镜像源解决方式
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8362057.html
Copyright © 2011-2022 走看看