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

来源:互联网 发布:金山数据恢复账号密码 编辑:程序博客网 时间:2024/06/02 02:18

利用合并的单调性,可以去掉优先队列得到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 1000000007int 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;}


0 0
原创粉丝点击