【BZOJ5249】IIIDX(贪心,线段树)

题意:

 思路:赛季结束之前余总推荐的一道好题,不愧是余总

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 }

猜你喜欢

转载自www.cnblogs.com/myx12345/p/11876834.html