• p4364 [九省联考2018]IIIDX


    传送门

    分析

    我们先考虑如果所有数都不相同我们应该怎么办

    我们可以直接贪心的在每个点放可行的最大权值

    但是题目要求可以有相同的数

    我们可以考虑每次让当前节点可发且尽量大的同时给兄弟节点留的数尽量大

    我们用线段树维护每个点比它大的点还剩几个

    对于每个点要给它的子树预留足够的点即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int n,fa[500100],siz[500100],d[2001000],col[2001000];
    int a[500100],ans[500100],cnt[500100]; 
    double f;
    inline bool cmp(const int x,const int y){return x>y;}
    inline void build(int le,int ri,int wh){
        if(le==ri){
          d[wh]=le;
          return;
        }
        int mid=(le+ri)>>1;
        build(le,mid,wh<<1);
        build(mid+1,ri,wh<<1|1);
        d[wh]=min(d[wh<<1],d[wh<<1|1]);
    }
    inline void update(int le,int ri,int wh,int x,int y,int k){
        if(le>=x&&ri<=y){
          d[wh]+=k;
          col[wh]+=k;
          return;
        }
        int mid=(le+ri)>>1;
        if(col[wh]!=0){
          d[wh<<1]+=col[wh];
          d[wh<<1|1]+=col[wh];
          col[wh<<1]+=col[wh];
          col[wh<<1|1]+=col[wh];
          col[wh]=0;
        }
        if(mid>=x)update(le,mid,wh<<1,x,y,k);
        if(mid<y)update(mid+1,ri,wh<<1|1,x,y,k);
        d[wh]=min(d[wh<<1],d[wh<<1|1]);
    }
    inline int q(int le,int ri,int wh,int k){
        if(le==ri)return d[wh]>=k?le:le+1;
        int mid=(le+ri)>>1;
        if(col[wh]!=0){
          d[wh<<1]+=col[wh];
          d[wh<<1|1]+=col[wh];
          col[wh<<1]+=col[wh];
          col[wh<<1|1]+=col[wh];
          col[wh]=0;
        }
        if(d[wh<<1|1]>=k)return q(le,mid,wh<<1,k);
          else return q(mid+1,ri,wh<<1|1,k);
    }
    int main(){
        int i,j,k;
        scanf("%d",&n);
        cin>>f;
        for(i=1;i<=n;i++)scanf("%d",&a[i]);
        for(i=1;i<=n;i++)fa[i]=i/f,siz[i]=1;
        sort(a+1,a+n+1,cmp);
        for(i=n;i>0;i--)siz[fa[i]]+=siz[i];
        for(i=n-1;i>0;i--)cnt[i]=(a[i]==a[i+1]?cnt[i+1]+1:0);
        build(1,n,1);
        for(i=1;i<=n;i++){
          if(fa[i]&&fa[i]!=fa[i-1])update(1,n,1,ans[fa[i]],n,siz[fa[i]]-1);
          int x=q(1,n,1,siz[i]);
          x+=cnt[x];
          ++cnt[x];
          ans[i]=x;
          update(1,n,1,x,n,-siz[i]);
        }
        for(i=1;i<=n;i++)printf("%d ",a[ans[i]]);
        return 0;
    }
  • 相关阅读:
    ASP.NET MVC4.0+ WebAPI+EasyUI+KnockOutJS快速开发框架 通用权限管理系统
    74.Java异常处理机制
    emmm
    数据库关系代数
    汇编实验二 2进制转16进制
    汇编实验一 显示字符串
    JustOj 1386: 众数的数量
    Codeforces 124A
    Codeforces 456A
    Codeforces 237A
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10605893.html
Copyright © 2020-2023  润新知