POJ 2442 Sequence (手写堆)

我晕啊,我的堆都是手写的,用的时间还是438ms ,他们的100+ms 是怎么写出来的啊...写一个最小堆,想死的心都有了..各种错..


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <map>
#include <string>
#define LL long long
#define DB double
#define SF scanf
#define PF printf
#define N 2009
#define bug cout<<"bug"<<endl;
using namespace std;
int ans[N],a[N],b[N];
int n,m;
struct nod{
    int val,l,r;
    bool operator<(const nod t)const
    {
        return val<t.val;
    }
} qq[N<<1];
struct heap{
    int n;
    void ini(){n=1;}
    void push(nod &t)
    {
        n++;
        int now=n-1;
        while(now>1)
        {
            if(t<qq[now>>1])
            {
                qq[now]=qq[now>>1];
                now>>=1;
            }else
            {
                qq[now] = t;
                return ;
            }
        }qq[now] = t;
    }
    nod top(){return qq[1];}
    void pop()
    {
        nod t = qq[--n];
        int tmp = 1,k;
        while((tmp<<1)<n)
        {
            k = tmp<<1;
            if(k+1<n&&qq[k+1]<qq[k])
            k = k+1;
            if(qq[k]<t)
            {
                qq[tmp] = qq[k];
                tmp = k;
            }else break;
        } qq[tmp] = t;
    }
} que;

int has[N*10];
const int MOD = 9997;
bool inhas(int k)
{
    int t = k%MOD;
    while(has[t]!=-1&&has[t]!=k)
    {
        t+= 997;
        if(t>=MOD) t-=MOD;
    }
    if(has[t]==k) return false;
    has[t] = k;
    return true;
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    int cas;SF("%d",&cas);
    while(cas--)
    {
        SF("%d%d",&m,&n);
        for(int i=0;i<n;i++) SF("%d",&ans[i]);sort(ans,ans+n);
        for(int i=1;i<m;i++)
        {
            que.ini();
            for(int j=0;j<n;j++) SF("%d",&a[j]);sort(a,a+n);
            memcpy(b,ans,sizeof(ans));
            nod e,t;e.l = 0;e.r = 0;e.val = a[0]+b[0];
            que.push(e);memset(has,-1,sizeof(has));
            for(int j=0;j<n;j++)
            {
                e = que.top();que.pop();
                ans[j] = e.val;
                t.l = e.l+1;t.r = e.r;t.val = a[t.l]+b[t.r];
                if(t.l<n&&inhas(t.l*N+t.r)) que.push(t);
                t.l = e.l;t.r = e.r+1;t.val = a[t.l]+b[t.r];
                if(t.r<n&&inhas(t.l*N+t.r)) que.push(t);
            }
        }
        for(int i=0;i<n;i++)
        {
            if(i) PF(" ");
            PF("%d",ans[i]);
        }puts("");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值