• luogu1631 序列合并


    题目

    https://www.luogu.org/problem/show?pid=1631

    题解

    应该是我的方法不是很优,这道题系统堆也是可以过的,但是我的过不掉

    那就干脆以这道题为例,比较一下系统堆和手写堆的速度

    方法就是先将b[1]与a[i]逐个相加,先全部push到堆里,再从2~n枚举b,依次与a中的数相加后与堆顶比较,若较小则更新堆中元素,若较大直接break(因为a是有序的,若当前值与b[i]相加大于堆顶,后面的一定均大于,无须比较),最后从小到大输出堆中元素

    代码(TLE)

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath> 
    #include <queue> 
    #define N 100005
    using namespace std; 
    
    int n,a[N],b[N],ans[N];
    priority_queue<int> q;
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        for(int i=1;i<=n;i++) q.push(a[i]+b[1]);
        for(int i=2;i<=n;i++)
        {
            int j=1;
            for(j;j<=n;j++)
            {
                int k=q.top();
                if(b[i]+a[j]<k) {q.pop();q.push(b[i]+a[j]);}
                else break;
            }
            if(j==1) break;
        }
        for(int i=1;i<=n;i++) {ans[i]=q.top();q.pop();}
        for(int i=n;i>=1;i--) printf("%d ",ans[i]);
        return 0;
    }
    

    image

    直接使用系统堆,可以得90分,并且第八九个点时长就比较大了

    代码(AC)

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cmath> 
    #include <queue> 
    #define inf 2147483646
    #define N 1000005
    using namespace std; 
    
    int n,a[N],b[N],ans[N];
    int q[N],sz;
    
    void push(int x)
    {
        q[++sz]=x;
        int pos=sz;
        while(pos>1&&q[pos>>1]<q[pos])
            swap(q[pos],q[pos>>1]),pos=pos>>1;
    }
    
    void pop()
    {
        int rt=q[sz--],pos=1;
        q[pos]=rt;
        while(true)
        {
            int lv=(pos<<1)>sz? -inf:q[pos<<1];
            int rv=(pos<<1|1)>sz? -inf:q[pos<<1|1];
            int v=max(lv,rv),nt=lv>rv? (pos<<1):(pos<<1|1);
            if(q[pos]<v)
                swap(q[pos],q[nt]),pos=nt;
            else break;
        }
    }
    
    int top() {return q[1];}
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1;i<=n;i++) scanf("%d",&b[i]);
        for(int i=1;i<=n;i++) push(a[i]+b[1]);
        for(int i=2;i<=n;i++)
        {
            int j=1;
            for(j;j<=n;j++)
            {
                int k=top();
                if(b[i]+a[j]<k) {pop();push(b[i]+a[j]);}
                else break;
            }
            if(j==1) break;
        }
        for(int i=1;i<=n;i++) {ans[i]=top();pop();}
        for(int i=n;i>=1;i--) printf("%d ",ans[i]);
        return 0;
    }
    

    image

    仅将系统堆改为手写堆,就A掉了此题,并且速度改善非常大

    总结

    在不开优化的情况下,C++STL的很多函数速度非常不理想,尽量手打

  • 相关阅读:
    课程一(Neural Networks and Deep Learning),第一周(Introduction to Deep Learning)—— 1、经常提及的问题
    递归、字节流、文件复制_DAY20
    IO概述、异常、File文件类_DAY19
    某书2018笔试题之薯券
    某书2018笔试题之翻转数字
    某书2018笔试题之字符串中最大子数字串
    批量发货的启示
    为什么易燥易怒以及柔润相处的练习
    编程漫谈(十五):编程与软件开发
    使用函数式编程消除重复无聊的foreach代码(Scala示例)
  • 原文地址:https://www.cnblogs.com/XYZinc/p/7363347.html
Copyright © 2020-2023  润新知