Problem Description
Recently, Bob has just learnt a naive sorting algorithm: merge sort. Now, Bob receives a task from Alice.
Alice will give Bob N sorted sequences, and the i -th sequence includes ai elements. Bob need to merge all of these sequences. He can write a program, which can merge no more than k sequences in one time. The cost of a merging operation is the sum of the length of these sequences. Unfortunately, Alice allows this program to use no more than T cost. So Bob wants to know the smallest k to make the program complete in time.
Alice will give Bob N sorted sequences, and the i -th sequence includes ai elements. Bob need to merge all of these sequences. He can write a program, which can merge no more than k sequences in one time. The cost of a merging operation is the sum of the length of these sequences. Unfortunately, Alice allows this program to use no more than T cost. So Bob wants to know the smallest k to make the program complete in time.
Input
The first line of input contains an integer
t0
, the number of test cases.
t0
test cases follow.
For each test case, the first line consists two integers N (2≤N≤100000) and T (∑Ni=1ai<T<231) .
In the next line there are N integers a1,a2,a3,...,aN(∀i,0≤ai≤1000) .
For each test case, the first line consists two integers N (2≤N≤100000) and T (∑Ni=1ai<T<231) .
In the next line there are N integers a1,a2,a3,...,aN(∀i,0≤ai≤1000) .
Output
For each test cases, output the smallest
k
.
Sample Input
1 5 25 1 2 3 4 5
Sample Output
3
Source
分析:二分+k叉哈夫曼树,注意(n-1) % (k-1) != 0时要特殊处理一下。
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<queue>
#define INF 0x3f3f3f3f
#define eps 1e-9
#define MOD 1000000007
#define MAXN 200005
using namespace std;
typedef long long ll;
int n,t,T,a[MAXN];
void nextInt(int &x) //输入外挂
{
char c;
do c = getchar(); while ( c < '0' || c > '9');
x = c-'0';
while ('0' <= (c = getchar()) && c<='9') x = x*10 + c - '0';
}
ll check(int mid)
{
deque <ll> q1,q2;
for(int i = 1;i <= n;i++) q1.push_back(a[i]);
int res = (n-1) % (mid-1);
ll tmp = 0,ans = 0;
if(res) res++;
for(int i = 1;i <= res;i++)
{
tmp += q1.front();
q1.pop_front();
}
ans += tmp;
if((n-1) % (mid-1)) q2.push_back(tmp);
while(q1.size() + q2.size() > 1)
{
ll tmp = 0;
for(int i = 1;i <= mid;i++)
{
if((q2.empty() || q1.front() < q2.front()) && q1.size())
{
tmp += q1.front();
q1.pop_front();
}
else
{
tmp += q2.front();
q2.pop_front();
}
}
ans += tmp;
q2.push_back(tmp);
}
return ans;
}
int main()
{
nextInt(T);
while(T--)
{
nextInt(n),nextInt(t);
for(int i = 1;i <= n;i++) nextInt(a[i]);
sort(a+1,a+1+n);
int l = 2,r = n;
while(l != r)
{
int mid = (l+r)/2;
if(check(mid) <= 1ll*t) r = mid;
else l = mid+1;
}
cout<<l<<endl;
}
}