hdu 5884二分+优先队列

来源:互联网 发布:团购网站 淘宝折扣 编辑:程序博客网 时间:2024/05/01 21:29


PS:当初比赛的时候总是超时,以后优先队列放在函数外边吧,能节省一些时间。然后怎么还是不能理解(n - 1)% (k - 1)== 0最小,然后当成一个结论来记吧,k叉哈夫曼树。


#include<bits/stdc++.h>using namespace std;typedef long long ll;typedef pair<int,int> P;typedef set<int>::iterator ITER;#define fi first#define se second#define INF 0x3f3f3f3f#define clr(x,y) memset(x,y,sizeof x)const int maxn = 1e5 + 10;//const int Mod = 1e9 + 7;//const int N = 2;/*                   _ooOoo_                  o8888888o                  88" . "88                  (| -_- |)                  O\  =  /O               ____/`---'\____             .'  \\|     |//  `.            /  \\|||  :  |||//  \           /  _||||| -:- |||||-  \           |   | \\\  -  /// |   |           | \_|  ''\---/''  |   |           \  .-\__  `-`  ___/-. /         ___`. .'  /--.--\  `. . __      ."" '<  `.___\_<|>_/___.'  >'"".     | | :  `- \`.;`\ _ /`;.`/ - ` : | |     \  \ `-.   \_ __\ /__ _/   .-` /  /======`-.____`-.___\_____/___.-`____.-'======                   `=---='^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^            pass System Test!*/int n;ll m;int a[maxn];int sum[maxn];priority_queue<ll,vector<ll>,greater<ll> >q;ll calc(int k){    while(!q.empty())q.pop();    ll ret = 0;    int temps = (n - 1)%(k - 1);    if(temps)temps += 1,ret += sum[temps],q.push(sum[temps]);    for(int i = temps + 1; i <= n; i ++)q.push(a[i]);    int tmp = (n - 1) / (k- 1);    while(tmp --)    {        ll temp = 0;        for(int i = 0; i < k; i ++)            temp += 1ll * q.top(),q.pop();        ret += temp;        q.push(temp);    }    return ret;}int main(){//    freopen("out.txt","r",stdin);    int Tcase;scanf("%d",&Tcase);    while(Tcase --)    {        scanf("%d%I64d",&n,&m);        for(int i = 1; i <= n; i ++)            scanf("%d",&a[i]);        sort(a + 1,a + n + 1);        sum[0] = 0;        for(int i = 1; i <= n; i ++)            sum[i] = sum[i - 1] + a[i];        if(n == 1)        {            puts("0");continue;        }        int l = 2,r = n;        int ans = 0;        while(l <= r)        {            int mid = (l + r) >> 1;            if(calc(mid) <= m)            {                ans = mid;r = mid - 1;            }            else l = mid + 1;        }        printf("%d\n",ans);    }    return 0;}