题解:P11523 [THUPC 2025 初赛] 摊位分配
lailai0916 · · 题解
解题思路
序列
枚举每个格子,每次从大顶堆中取出权值最大的社团,将该格子分配给该社团,并将其权值减半后重新放回堆中。这种方法的时间复杂度为
考虑优化,注意到任意权值
此时有个很好的性质,即对于任意
设还剩
显然,对于每个
参考代码
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=100005;
struct Node
{
int id,cnt;
double val,st;
bool operator<(const Node &rhs) const
{
if(val!=rhs.val)return val<rhs.val;
if(cnt==0^rhs.cnt==0)return cnt;
if(st!=rhs.st)return st<rhs.st;
return id>rhs.id;
}
}a[N];
int ans[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n,k;
cin>>n>>k;
priority_queue<Node> q;
for(int i=1;i<=n;i++)
{
double x;
cin>>x;
q.push({i,0,x,x});
}
while(!q.empty()&&k)
{
Node u=q.top();
if(u.val<2)break;
q.pop();
u.cnt++;
u.val/=2;
q.push(u);
k--;
}
while(!q.empty())
{
Node u=q.top();
q.pop();
a[u.id]=u;
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
ans[a[i].id]=a[i].cnt+k/n+(i>n-k%n);
}
for(int i=1;i<=n;i++)
{
cout<<ans[i]<<' ';
}
return 0;
}