您的位置:首页 > 其它

2016 ACM/ICPC Asia Regional Qingdao Online hdu 5884 Sort (智商+队列)★

2016-09-17 19:13 501 查看
利用合并的单调性,可以去掉优先队列得到
O(n
\log n)O(nlogn)
的做法:先对所有数排序,另外一个队列维护合并后的值,取值时从两个序列前端取小的即可。

借鉴别人的思路,好简单啊 

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
#include <bitset>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF  0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-3
#define maxn 100100
#define MOD 1000000007

int n;
long long m;
int a[maxn];

int solve(int x)
{
int cnt = n;
while(cnt >= x)
cnt -= x-1;
return x - cnt;
}
int main()
{
int t,C = 1;
scanf("%d",&t);
while(t--)
{
scanf("%d%lld",&n,&m);
for(int i = 0; i < n; i++)
scanf("%d",&a[i]);
sort(a,a+n);
int l = 1,r = n;
while(r - l > 1)
{
int mid = (l+r) / 2;
queue<int> q1,q2;
int k = solve(mid);
if(k != mid-1)
{
for(int i = 0; i < k; i++)
q1.push(0);
}
for(int i = 0; i < n; i++)
q1.push(a[i]);
long long ssum = 0;
while(!q1.empty() || !q2.empty())
{
int cnt = 0;
long long sum = 0;
while(cnt < mid)
{
if(q1.empty() && q2.empty())
break;
if(!q1.empty() && !q2.empty())
{
if(q1.front() < q2.front())
{
sum += q1.front();
q1.pop();
}
else
{
sum += q2.front();
q2.pop();
}
}
else if(!q1.empty())
{
sum += q1.front();
q1.pop();
}
else
{
sum += q2.front();
q2.pop();
}
cnt++;
}
if(cnt <= 1)
break;
q2.push(sum);
ssum += sum;
if(ssum > m)
break;
}
if(ssum <= m)
r = mid;
else
l = mid;
}
printf("%d\n",r);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐