[BZOJ5249][2018多省省队联测]IIIDX:贪心,线段树

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cmath>
 6 #include <algorithm>
 7 using namespace std;
 8 inline int read(){
 9     int x=0,f=1;char ch=getchar();
10     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
11     while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
12     return x*f;
13 }
14 const int MAXN=500005;
15 int n;double kk;
16 int d[MAXN],fa[MAXN],siz[MAXN],cnt[MAXN],ans[MAXN];bool vis[MAXN];
17 int minn[MAXN*4],tag[MAXN*4],ql,qr,k,loc;
18 bool cmp(int a,int b){
19     return a>b;
20 }
21 #define mid ((l+r)>>1)
22 #define lc (o<<1)
23 #define rc ((o<<1)|1)
24 void build(int o,int l,int r){
25     if(l==r){
26         minn[o]=l;
27         return;
28     }
29     build(lc,l,mid);
30     build(rc,mid+1,r);
31     minn[o]=min(minn[lc],minn[rc]);
32 }
33 inline void pushdown(int o){
34     if(!tag[o]) return;
35     minn[lc]+=tag[o];
36     minn[rc]+=tag[o];
37     tag[lc]+=tag[o];
38     tag[rc]+=tag[o];
39     tag[o]=0;
40 }
41 void upd(int o,int l,int r){
42     if(ql<=l&&r<=qr){
43         minn[o]+=k;
44         tag[o]+=k;
45         return;
46     }
47     pushdown(o);
48     if(mid>=ql) upd(lc,l,mid);
49     if(mid<qr) upd(rc,mid+1,r);
50     minn[o]=min(minn[lc],minn[rc]); 
51 }
52 int query(int o,int l,int r){
53     if(l==r) return (minn[o]>=k?l:l+1);
54     pushdown(o);
55     if(minn[rc]>=k) return query(lc,l,mid);
56     else return query(rc,mid+1,r);
57 }
58 int main(){
59     memset(minn,0x3f,sizeof minn);
60     n=read();scanf("%lf",&kk);
61     for(int i=1;i<=n;i++){
62         d[i]=read();
63     }
64     sort(d+1,d+n+1,cmp);
65     for(int i=n-1;i;i--){
66         if(d[i]==d[i+1]) cnt[i]=cnt[i+1]+1;
67     }
68     for(int i=n;i;i--){
69         siz[i]+=1;
70         fa[i]=floor(i*1.0/kk);
71         siz[fa[i]]+=siz[i];
72     }
73     build(1,1,n);
74     for(int i=1;i<=n;i++){
75         if(fa[i]&&!vis[fa[i]]){
76             vis[fa[i]]=1;
77             ql=ans[fa[i]],qr=n,k=siz[fa[i]]-1;
78             upd(1,1,n);
79         }
80         k=siz[i];
81         int pos=query(1,1,n);
82         pos+=cnt[pos];
83         cnt[pos]++;
84         pos-=cnt[pos]-1;
85         ans[i]=pos;
86         ql=ans[i],qr=n,k=-siz[i];
87         upd(1,1,n);
88     }
89     for(int i=1;i<=n;i++){
90         printf("%d ",d[ans[i]]);
91     }
92     return 0;
93 }

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9281356.html