题意:
思路:赛季结束之前余总推荐的一道好题,不愧是余总
From https://www.cnblogs.com/suika/p/8748115.html
简略的说就是在预留足够多的位置的前提下贪心取最大的数字
剩余可以使用的数字可以使用线段树维护,每次查询可以使用的最大的数字也可以在线段树上二分
维护相同的数字未被使用的的最大的位置的技巧可以学习一下
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 typedef unsigned int uint; 5 typedef unsigned long long ull; 6 typedef long double ld; 7 typedef pair<int,int> PII; 8 typedef pair<ll,ll> Pll; 9 typedef vector<int> VI; 10 typedef vector<PII> VII; 11 typedef pair<ll,ll>P; 12 #define N 500010 13 #define M 1000000 14 #define INF 1e9 15 #define fi first 16 #define se second 17 #define MP make_pair 18 #define pb push_back 19 #define pi acos(-1) 20 #define mem(a,b) memset(a,b,sizeof(a)) 21 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++) 22 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--) 23 #define lowbit(x) x&(-x) 24 #define Rand (rand()*(1<<16)+rand()) 25 #define id(x) ((x)<=B?(x):m-n/(x)+1) 26 #define ls p<<1 27 #define rs p<<1|1 28 #define fors(i) for(auto i:e[x]) if(i!=p) 29 30 const int MOD=1e8+7,inv2=(MOD+1)/2; 31 int p=1e4+7; 32 double eps=1e-8; 33 int dx[4]={-1,1,0,0}; 34 int dy[4]={0,0,-1,1}; 35 36 struct node 37 { 38 int s,tag; 39 }t[N<<2]; 40 41 int a[N],b[N],c[N],fa[N],ans[N],sz[N]; 42 43 int read() 44 { 45 int v=0,f=1; 46 char c=getchar(); 47 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 48 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 49 return v*f; 50 } 51 52 ll readll() 53 { 54 ll v=0,f=1; 55 char c=getchar(); 56 while(c<48||57<c) {if(c=='-') f=-1; c=getchar();} 57 while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar(); 58 return v*f; 59 } 60 61 bool cmp(int a,int b) 62 { 63 return a>b; 64 } 65 66 void pushup(int p) 67 { 68 t[p].s=min(t[ls].s,t[rs].s); 69 } 70 71 void pushdown(int p) 72 { 73 if(t[p].tag) 74 { 75 t[ls].s+=t[p].tag; 76 t[rs].s+=t[p].tag; 77 t[ls].tag+=t[p].tag; 78 t[rs].tag+=t[p].tag; 79 t[p].tag=0; 80 } 81 } 82 83 void build(int l,int r,int p) 84 { 85 if(l==r) 86 { 87 t[p].s=l; 88 t[p].tag=0; 89 return; 90 } 91 int mid=(l+r)>>1; 92 build(l,mid,ls); 93 build(mid+1,r,rs); 94 pushup(p); 95 } 96 97 void update(int l,int r,int x,int y,int d,int p) 98 { 99 if(x<=l&&r<=y) 100 { 101 t[p].s+=d; 102 t[p].tag+=d; 103 return; 104 } 105 pushdown(p); 106 int mid=(l+r)>>1; 107 if(x<=mid) update(l,mid,x,y,d,ls); 108 if(y>mid) update(mid+1,r,x,y,d,rs); 109 pushup(p); 110 } 111 112 int query(int l,int r,int x,int p) 113 { 114 if(l==r) 115 { 116 if(t[p].s>=x) return l; 117 else return (l+1); 118 } 119 pushdown(p); 120 int mid=(l+r)>>1; 121 if(t[rs].s>=x) return query(l,mid,x,ls); 122 else return query(mid+1,r,x,rs); 123 } 124 125 int main() 126 { 127 int n=read(); 128 double K; 129 scanf("%lf",&K); 130 rep(i,1,n) a[i]=read(),sz[i]=1; 131 sort(a+1,a+n+1,cmp); 132 per(i,n-1,1) 133 if(a[i]==a[i+1]) c[i]=c[i+1]+1; 134 else c[i]=0; 135 rep(i,1,n) fa[i]=(int)((double)i/K+eps); 136 per(i,n,1) sz[fa[i]]+=sz[i]; 137 build(1,n,1); 138 rep(i,1,n) 139 { 140 if(fa[i]&&!b[fa[i]]) 141 { 142 update(1,n,ans[fa[i]],n,sz[fa[i]]-1,1); 143 b[fa[i]]=1; 144 } 145 int x=query(1,n,sz[i],1); 146 x+=c[x]; c[x]++; x-=(c[x]-1); ans[i]=x; 147 update(1,n,x,n,-sz[i],1); 148 } 149 rep(i,1,n-1) printf("%d ",a[ans[i]]); 150 printf("%d\n",a[ans[n]]); 151 return 0; 152 }