• 未曾设想的道路(线段树)


    https://ac.nowcoder.com/acm/contest/11244/C

    题解:

    考虑只需要区间修改,求历史最大值

    那么用线段树的话我们需要维护历史标记最大值,当前标记,区间当前最大值,历史区间最大值

    其实现在变成求历史K大可以类似维护

    我们维护历史标记最大的K个,当前标记,区间当前最大的K个,区间历史最大的K个

    这样子updata的时候是比较显然的两个数组扫一下 复杂度O(logn*K)

    down的时候一方面要维护历史标记最大值,这个是O(logn*K)的

    另一方面要更新历史区间最大值,这是个堆的经典问题 复杂度O(logn*logk*k)

    所以总时间复杂度O(nlognK+mlogn*logk*k)

    因为down是瓶颈注意标记判一下有标记再down

    代码:

    #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4.1,sse4.2,avx,avx2,popcnt,tune=native")
    
    //#include <immintrin.h>
    //#include <emmintrin.h>
    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i,h,t) for (int i=h;i<=t;i++)
    #define dep(i,t,h) for (int i=t;i>=h;i--)
    #define ll long long
    #define me(x) memset(x,0,sizeof(x))
    #define mep(x,y) memcpy(x,y,sizeof(y))
    #define IL inline
    #define rint register int
    #define mp make_pair
    inline ll rd(){
        ll x=0;char c=getchar();bool f=0;
        while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
        while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
        return f?-x:x;
    }
    char ss[1<<24],*A=ss,*B=ss;
    IL char gc()
    {
        return A==B&&(B=(A=ss)+fread(ss,1,1<<24,stdin),A==B)?EOF:*A++;
    }
    template<class T>void maxa(T &x,T y)
    {
        if (y>x) x=y;
    }
    template<class T>void mina(T &x,T y)
    {
        if (y<x) x=y;
    }
    template<class T>void read(T &x)
    {
        int f=1,c; while (c=gc(),c<48||c>57) if (c=='-') f=-1; x=(c^48);
        while(c=gc(),c>47&&c<58) x=x*10+(c^48); x*=f;
    }
    const int mo=1e9+7;
    ll fsp(int x,int y)
    {
        if (y==1) return x;
        ll ans=fsp(x,y/2);
        ans=ans*ans%mo;
        if (y%2==1) ans=ans*x%mo;
        return ans;
    }
    struct cp {
        ll x,y;
        cp operator +(cp B)
        {
            return (cp){x+B.x,y+B.y};
        }
        cp operator -(cp B)
        {
            return (cp){x-B.x,y-B.y};
        }
        ll operator *(cp B)
        {
            return x*B.y-y*B.x;
        }
        int half() { return y < 0 || (y == 0 && x < 0); }
    };
    struct re{
        int a,b,c;
    };
    const int N=1.1e5;
    int a[N];
    const int Mx=100;
    #define mid ((h+t)/2)
    struct sgt{
        int v1[N*4][101],v2[N*4][101],lz1[N*4],lz[N*4][101];
        sgt()
        {
            rep(i,0,N*4-1)
            {
              rep(j,0,100) v2[i][j]=lz[i][j]=v1[i][j]=-1e9;
              v1[i][1]=0;
            }
        }
        inline void g(int *a,int *b)
        {
            int c[101];
            int x=1,y=1;
            rep(i,1,Mx)
              if (a[x]>b[y]) c[i]=a[x++];
              else c[i]=b[y++];
            mep(a,c);
        }
        inline void updata(int x)
        {
            mep(v2[x],v2[x*2]);
            g(v2[x],v2[x*2+1]);
            mep(v1[x],v1[x*2]);
            g(v1[x],v1[x*2+1]);
        }
        void build(int x,int h,int t)
        {
            if (h==t)
            {
                v1[x][1]=v2[x][1]=a[h];
                return;
            }
            build(x*2,h,mid); build(x*2+1,mid+1,t);
            updata(x);
        }
        inline void g2(int *a,int *b,int *c)
        {
            priority_queue<pair<int,int> > M; 
            int h[101];
            rep(i,1,Mx) M.push(mp(b[i]+c[1],i)),h[i]=1;
            rep(i,1,Mx)
            {
                auto x=M.top();
                a[i]=max((int)(-1e9),x.first);
                M.pop();
                int y=x.second;
                h[y]++;
                M.push(mp(b[y]+c[h[y]],y));
            }
        }
        inline void down(int x)
        {
            if (lz[x][1]>-1e8)
            {
              rep(r,x*2,x*2+1)
              {
                int b[101];
                rep(i,1,Mx) b[i]=lz[x][i]+lz1[r];
                g(lz[r],b);
                lz1[r]+=lz1[x];
                g2(b,v1[r],lz[x]);
                g(v2[r],b);
                rep(i,1,Mx) v1[r][i]=v1[r][i]+lz1[x];
              }
              lz1[x]=0;
              rep(i,1,Mx) lz[x][i]=-1e9;
            }
        }
        void add(int x,int h,int t,int h1,int t1,int k)
        {
            if (h1<=h&&t<=t1)
            {
                lz1[x]+=k;
                int h[101];
                h[1]=lz1[x]; rep(i,2,100) h[i]=-1e9;
                g(lz[x],h);
                rep(i,1,Mx) v1[x][i]=v1[x][i]+k;
                g(v2[x],v1[x]);
                return;
            }
            down(x);
            if (h1<=mid) add(x*2,h,mid,h1,t1,k);
            if (mid<t1) add(x*2+1,mid+1,t,h1,t1,k);
            updata(x);
        }
        void query(int x,int h,int t,int h1,int t1,int *a)
        {
            if(h1<=h&&t<=t1)
            {
                g(a,v2[x]); return;
            }
            down(x);
            if (h1<=mid) query(x*2,h,mid,h1,t1,a);
            if (mid<t1) query(x*2+1,mid+1,t,h1,t1,a);
        }
    }S;
    int main()
    {
       freopen("11.in","r",stdin);
       freopen("11.out","w",stdout);
       ios::sync_with_stdio(false);
       int n,m;
       cin>>n>>m;
       rep(i,1,n) cin>>a[i];
       S.build(1,1,n);
      /* rep(i,1,n)
       { 
         if (i==2e4) return 0;
         cout<<i<<endl;
         S.add(1,1,n,i,i,a[i]);
       } */
       //return 0;
       rep(i,1,m)
       {
       //    if (i%100==0) cerr<<i<<endl;
            int kk,l,r,x;
            cin>>kk>>l>>r>>x;
            if (kk==0) S.add(1,1,n,l,r,x);
            else
            {
                int ans[101];
                rep(i,1,100) ans[i]=-1e9;
                S.query(1,1,n,l,r,ans);
                int pp;
            //    rep(i,1,x) cout<<ans[i]<<" ";
           //     cout<<endl;
                rep(i,1,x) if (ans[i]>-1e8) pp=ans[i];
                cout<<pp<<endl;
            }
       }
       return 0;
    }
    View Code
  • 相关阅读:
    rancher 2.X 搭建小型web集群+mysql主从复制
    harbor 仓库搭建
    k8s 集群搭建
    oracle sql命令
    IIS实现反向代理
    高并发的大型网站架构设计
    .net core集成vue
    使用TFS玩转Docker自动化部署
    动态创建IIS站点
    网站架构设计(草稿)
  • 原文地址:https://www.cnblogs.com/yinwuxiao/p/14862300.html
Copyright © 2020-2023  润新知