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
二分k
然后就是k叉的哈夫曼树
我们可以直接把原数列sort一下
然后用两个数列维护。每次计算结果放第二个数列中,再每次比较两格数列的头指针的数哪个小,累加
因为数组可以在二分外面直接排序,这样就比直接用堆做少了一个log
#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct number
{
long long x;
bool operator <(number y) const
{
return x>y.x;
}
}b[100001];
int a[100001];
int n;
long long t;
priority_queue<number> Q;
long long q1[1000001],q2[1000001];
inline bool check(int limit)
{
int i,j;
int l1=1,r1=0,l2=1,r2=0;
int m=limit-1;
int tt=n;
while(tt%m!=1&&m!=1)
{
r1++;
q1[r1]=0;
tt++;
}
for(i=1;i<=n;i++)
{
r1++;
q1[r1]=a[i];
}
long long sum=0,ans=0;
/* for(i=1;i<=((n-1)-1)%m+1;i++)
{ vv
l1++;
sum+=q1[l1];
}*/
ans+=sum;
// r2++;
// q2[r2]=sum;
for(i=1;i<=tt/m;i++)
{
sum=0;
int sx=0;
while(sx<limit&&l1<=r1&&l2<=r2)
{
if(q1[l1]<=q2[l2])
{
sum+=q1[l1];
l1++;
}
else
{
sum+=q2[l2];
l2++;
}
sx++;
}
if(sx<limit)
{
if(l1<=r1)
{
while(sx<limit)
{
sum+=q1[l1];
l1++;
sx++;
}
}
else
{
while(sx<limit)
{
sum+=q2[l2];
l2++;
sx++;
}
}
}
r2++;
q2[r2]=sum;
ans+=sum;
}
return ans<=t;
}
int main()
{
int T;
scanf("%d",&T);
while(T>0)
{
T--;
scanf("%d%I64d",&n,&t);
int i;
for(i=1;i<=n;i++)
scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(i=1;i<=n;i++)
b[i].x=a[i];
int l=2,r=n;
while(l<=r)
{
int mid=(l+r)/2;
if(check(mid))
r=mid-1;
else
l=mid+1;
}
printf("%d\n",l);
}
return 0;
}