• [题解](堆)luogu_P1631序列合并


    思路来自题解

    作者: Red_w1nE 更新时间: 2016-11-13 20:46  在Ta的博客查看  72 


    最近有点忙 没时间贴代码了==

    【分析】

    首先,把A和B两个序列分别从小到大排序,变成两个有序队列。这样,从A和B中各任取一个数相加得到N^2个和,可以把这些和看成形成了n个有序表/队列:

    A[1]+B[1] <= A[1]+B[2] <= … <= A[1]+B[N]

    A[2]+B[1] <= A[2]+B[2] <= … <= A[2]+B[N]

    ……

    A[N]+B[1] <= A[N]+B[2] <= … <= A[N]+B[N]

    接下来,就相当于要将这N个有序队列进行合并排序:

    首先,将这N个队列中的第一个元素放入一个堆中;

    然后;每次取出堆中的最小值。若这个最小值来自于第k个队列,那么,就将第k个队列的下一个元素放入堆中。

    时间复杂度:O(NlogN)。

    priority_queue<int, vector<int>,greater<int> > q;

    分析过程可能是这样的:事实上我们不需要把所有的a[i]和b[i]的和全部存下来,因为序列的单调性,所以我们先用a中的最小值和其他b中所有值加起来

    对于每个b[i]来说都一定是当前对应最小的值,所以对b[i]来说,其他和b[i]不对应的a目前不会成为答案,也就没必要把他们加到堆里

    当当前这个用过后,下一个a就有可能成为答案了,所以再把下一个a加进堆

    不同的理解方法吧

    题解中还有用二分做的

    类似的题:luogu_P2085最小函数值

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=100010;
    int n,a[maxn],b[maxn];
    struct node{
        int x,k1,k2;
        node(int xx,int kk1,int kk2){
            x=xx,k1=kk1,k2=kk2;
        }
        bool operator <(const node &a)const{
            return x>a.x;
        }
    };
    priority_queue<node>q;
    int ans[maxn],cnt;
    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(node(a[i]+b[1],i,1));
        while(cnt<=n){
            int x=q.top().x,k1=q.top().k1,k2=q.top().k2;q.pop();
            ans[++cnt]=x;
            q.push(node(a[k1]+b[k2+1],k1,k2+1));
        }
        sort(ans+1,ans+1+n);
        for(int i=1;i<=n;i++)printf("%d ",ans[i]);
    }
  • 相关阅读:
    【Python】ModuleNotFoundError: No module named 'matplotlib.pyplot'
    【DB2】DB2使用IMPORT命令导入含有自增长列的表报错处理
    ~~
    汉字的unicode码范围是多少?
    字符编码(ASCII,Unicode和UTF-8) 和 大小端(zz)
    是否 whether ,if
    定语从句:
    by,with
    C++中extern “C”含义深层探索
    安装Office2007时出现1706错误的解决方案
  • 原文地址:https://www.cnblogs.com/superminivan/p/10776612.html
Copyright © 2020-2023  润新知