zoukankan      html  css  js  c++  java
  • uoj228:基础数据结构练习题

    题意:http://uoj.ac/problem/228

    sol  :线段树开根操作

       对于节点x,可以在max[x]-min[x]<=1时直接做,转化为区间减或区间覆盖

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #define int long long
    using namespace std;
    const int Mx=800010;
    int n,m,a[Mx],Min[Mx],Max[Mx],sum[Mx];
    int l[Mx],r[Mx],lson[Mx],rson[Mx],Add_tag[Mx],Cover_tag[Mx];
    
    void pushup(int x)
    {
        int L=lson[x],R=rson[x];
        Min[x]=min(Min[L],Min[R]);
        Max[x]=max(Max[L],Max[R]);
        sum[x]=sum[L]+sum[R];
    }
    
    void build(int x,int L,int R)
    {
        l[x]=L,r[x]=R,lson[x]=x<<1,rson[x]=x<<1|1;
        if(L==R) { Min[x]=a[L],Max[x]=a[L],sum[x]=a[L]; return ;}
        int mid=(L+R)>>1;
        build(x<<1,L,mid);
        build(x<<1|1,mid+1,R);
        pushup(x);
    }
    
    void pushdown(int x)
    {
        int LS=lson[x],RS=rson[x],LL=l[LS],LR=r[LS],RL=l[RS],RR=r[RS];
        if(Add_tag[x]!=0)
        {
            Max[LS]+=Add_tag[x],Min[LS]+=Add_tag[x],sum[LS]+=(LR-LL+1)*Add_tag[x];
            Max[RS]+=Add_tag[x],Min[RS]+=Add_tag[x],sum[RS]+=(RR-RL+1)*Add_tag[x];
            if(Cover_tag[LS]<1e8) Cover_tag[LS]+=Add_tag[x];
            else Add_tag[LS]+=Add_tag[x];
            if(Cover_tag[RS]<1e8) Cover_tag[RS]+=Add_tag[x];
            else Add_tag[RS]+=Add_tag[x];
        }
        if(Cover_tag[x]<1e8)
        {
            Max[LS]=Cover_tag[x],Min[LS]=Cover_tag[x],sum[LS]=(LR-LL+1)*Cover_tag[x];
            Max[RS]=Cover_tag[x],Min[RS]=Cover_tag[x],sum[RS]=(RR-RL+1)*Cover_tag[x];
            Cover_tag[LS]=Cover_tag[x];
            Cover_tag[RS]=Cover_tag[x];
        }
        Add_tag[x]=0,Cover_tag[x]=1e9;
    }
    
    void Add(int x,int ql,int qr,int val)
    {
        int L=l[x],R=r[x];
        if(ql>R||qr<L) return ;
        if(ql<=L&&qr>=R)
        {
            if(Cover_tag[x]<1e8) Cover_tag[x]+=val;
            else Add_tag[x]+=val;
            Max[x]+=val,Min[x]+=val,sum[x]+=(R-L+1)*val;
            return ;
        }
        pushdown(x);
        Add(lson[x],ql,qr,val);
        Add(rson[x],ql,qr,val);
        pushup(x);
    }
    
    void Cover(int x,int ql,int qr,int val)
    {
        int L=l[x],R=r[x];
        Add_tag[x]=0,Cover_tag[x]=val;
        Max[x]=val,Min[x]=val,sum[x]=(R-L+1)*val;
    }
    
    void Sqrt(int x,int ql,int qr)
    {
        int L=l[x],R=r[x];
        if(ql>R||qr<L) return ;
        if(ql<=L&&qr>=R&&Max[x]-Min[x]<=1)
        {
            int mx=(int)sqrt(Max[x]),mn=(int)sqrt(Min[x]);
            if(mx==mn) Cover(x,L,R,mx);
            else Add(x,L,R,mx-Max[x]);
            return ;
        }
        pushdown(x);
        Sqrt(lson[x],ql,qr);
        Sqrt(rson[x],ql,qr);
        pushup(x);
    }
    
    int Query(int x,int ql,int qr)
    {
        int L=l[x],R=r[x];
        if(ql>R||qr<L) return 0;
        if(ql<=L&&qr>=R) return sum[x];
        pushdown(x);
        int ans=Query(lson[x],ql,qr)+Query(rson[x],ql,qr);
        pushup(x);
        return ans;
    }
    
    signed main()
    {
        for(int i=0;i<Mx;i++) Cover_tag[i]=1e9;
        scanf("%lld%lld",&n,&m);
        for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
        build(1,1,n);
        for(int i=1,num,x,y,z;i<=m;i++)
        {
            scanf("%lld%lld%lld",&num,&x,&y);
            if(num==1) scanf("%lld",&z),Add(1,x,y,z);
            if(num==2) Sqrt(1,x,y);
            if(num==3) printf("%lld
    ",Query(1,x,y));
        }
        return 0;
    }
  • 相关阅读:
    网站宣传【免费】
    gridview行链接
    提前预告
    C#中var、int、object性能比较
    20部软件测试视频教程整合
    PO、VO、DTO、POJO
    云计算、虚拟化、容器
    Linux打包和压缩的区别
    Linux之Shell定时备份数据库
    luogu P1997 faebdc的烦恼 | 莫队
  • 原文地址:https://www.cnblogs.com/xiaoxubi/p/6639148.html
Copyright © 2011-2022 走看看