zoukankan      html  css  js  c++  java
  • Codeforces 912 E.Prime Gift (折半枚举、二分)

    题目链接:Prime Gift

    题意:

      给出了n(1<=n<=16)个互不相同的质数pi(2<=pi<=100),现在要求第k大个约数全在所给质数集的数。(保证这个数不超过1e18)

    题解:

      如果暴力dfs的话肯定超时间,其实给的n数据范围最大是16是一个很奇妙的数(一般折半枚举基本上是这样的数据范围@。@~)。所以想到折半枚举,把所有的质数分成两份求出每份中所有小于1e18的满足条件的数。然后二分答案,写cheak函数时遍历第一个集合,对第二个集合二分(折半枚举基本上这个套路)。但是,这里一定要注意的是这里折半枚举指的并不是将n分成两份求出两个集合,而是要让分出的两份数所形成的集合中所含的个数接近,因为用较小的数形成的集合个数要多很多(被这个点卡了好久#。#)。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int MAX_N = 1e4+9;
     4 const long long INF = 1e18;
     5 long long N,M,T,k;
     6 long long vec[2][MAX_N];
     7 vector<long long> st[2];
     8 void dfs(int l,int r,long long rt,int id)
     9 {
    10     st[id].push_back(rt);
    11     for(int i=l;i<r;i++)
    12     {
    13         if(INF/vec[id][i] >= rt)
    14             dfs(i,r,rt*vec[id][i],id);
    15     }
    16 }
    17 long long cheak_num(long long x)
    18 {
    19     long long ans = 0;
    20     for(int i=0;i<st[0].size();i++)
    21     {
    22         if(st[0][i] )
    23         ans += upper_bound(st[1].begin(),st[1].end(),x/st[0][i]) - st[1].begin();
    24     }
    25     return ans;
    26 }
    27 int main()
    28 {
    29     while(cin>>N)
    30     {
    31         st[0].clear();st[1].clear();
    32         for(int i=0;i<min((long long)5,N);i++) scanf("%lld",&vec[0][i]);
    33         for(int i=0;i<N-min((long long)5,N);i++) scanf("%lld",&vec[1][i]);
    34         dfs(0,min((long long)5,N),1,0);
    35         dfs(0,N-min((long long)5,N),1,1);
    36         for(int i=0;i<2;i++)
    37             sort(st[i].begin(),st[i].end());
    38             
    39         cin>>k;
    40         long long l=1,r=INF;
    41         while(l<=r)
    42         {
    43             long long mid = (l+r)>>1;
    44             if(cheak_num(mid) < k) l = mid+1;
    45             else r = mid-1;
    46         }
    47         cout<<l<<endl;
    48     }
    49     return 0;
    50 }
    51 /*
    52 16
    53 2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53
    54 755104793
    55 */
  • 相关阅读:
    Linux/Ubuntu tree 命令以树形结构显示文件夹目录结构
    apt-get install的默认安装路径
    error: (-215:Assertion failed) !_src.empty() in function 'cv::cvtColor'
    利用keras进行手写数字识别模型训练,并输出训练准确度
    OpenCV:图像的合并和切分
    OpenCV:图像的按位运算
    OpenCV:增加和减少图像的亮度,图像的加减法
    OpenCV:获取图像当中某一点的坐标
    OpenCV:图像的裁剪
    OpenCV:图像的水平、垂直、水平垂直翻转
  • 原文地址:https://www.cnblogs.com/doggod/p/8414075.html
Copyright © 2011-2022 走看看