• Prime Gift(prime)


    Prime Gift(prime)

    题目描述

     

    Jyt有nn个质数,分别为p1,p2,p3…,pnp1,p2,p3…,pn。

    她认为一个数xx是优秀的,当且仅当xx的所有质因子都在这nn个质数中。

    她想知道第kk大的优秀的数是多少。保证答案不超过10181018。

     

    输入

     

    第一行一个整数nn,表示质数的个数。

    第二行nn个升序排列的质数,第ii个数表示pipi。

    第三行一个整数kk,表示要求的是第kk大的数。

     

    输出

     

    一行,表示第kk大的优秀的数。

     

    样例输入

    <span style="color:#333333"><span style="color:#333333">#### 样例输入1
    3
    2 3 5
    7
    #### 样例输入2
    5
    3 7 11 13 31
    17</span></span>

    样例输出

    <span style="color:#333333"><span style="color:#333333"> 样例输出1
    8
     样例输出2
    93</span></span>

    提示

     

    数据规模及约定

    对于10%的数据,n≤2n≤2。

    对于30%的数据,n≤5n≤5。

    对于60%的数据,n≤10n≤10。

    对于100%的数据,n≤16,2≤pi≤100n≤16,2≤pi≤100。

     

    来源

    Codeforces912E


    solution

    神奇题

    考虑爆搜,显然数目太多了。

    把数字分为两组,可以奇数下标一组,偶数下标一组

    有点像meet-in-middle

    但这样我们没法一次算出答案。

    再二分一下即可。

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #define ll long long
    #define Top 1e18
    using namespace std;
    int k,n,s[20];
    ll q1[5000005],q2[5000005],l,r,t1,t2;
    ll pd(ll num)
    {
        ll cnt=0,p=t2;
        for(int i=1;i<=t1;i++){
            while(q2[p]>num/q1[i])p--;
            cnt+=p;
        }
        return cnt;
    }
    void dfs(ll x,int las){
        q1[++t1]=x;
        for(int i=las;i<=k;i+=2){
            if(x<=Top/(ll)s[i])dfs(s[i]*x,i);
        }
    }
    void DFS(ll x,int las){
        q2[++t2]=x;
        for(int i=las;i<=k;i+=2){
            if(x<=Top/(ll)s[i])DFS(s[i]*x,i);
        }
    }
    int main()
    {
        cin>>k;
        for(int i=1;i<=k;i++){
            scanf("%d",&s[i]);
        }  
        cin>>n;
        dfs(1,1);DFS(1,2);
         
        sort(q1+1,q1+t1+1);
        sort(q2+1,q2+t2+1);
        l=1,r=1e18;
         
        while(l<r){
            //cout<<l<<' '<<r<<endl;
            ll mid=l+r>>1;
            ll t=pd(mid);
            if(t<n)l=mid+1;
            if(t==n)r=mid;
            if(t>n) r=mid-1; 
        }
        cout<<l<<endl;
        return 0;
    }
  • 相关阅读:
    [BZOJ] 3191 [JLOI2013]卡牌游戏
    [LUOGU] P1466 集合 Subset Sums
    [LUOGU] P1113 杂物
    [BZOJ] 1003 [ZJOI2006]物流运输
    poj 2479 最大连续子段和
    C#学习第九弹之委托
    C#学习第八弹之线程基础理解
    C#学习第七弹之WPF
    hdu 2030 汉字的编码方式
    hdu 1559 暴力
  • 原文地址:https://www.cnblogs.com/liankewei/p/10358796.html
Copyright © 2020-2023  润新知