• CF912E Prime Gift


    传送门

    看到(n)只有16,可以把这些质数分成两半,然后预处理出这些数相乘得出的小于(10^{18})的所有数,排个序,然后二分最终答案,再用两个指针从前往后和从后往前扫,进行(two-pointers)统计答案是第几个,然后再搞搞救星了

    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    #define LL long long
    #define il inline
    #define re register
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define db double
    #define eps (1e-5)
    
    using namespace std;
    const int M=2000000+10;
    const LL inf=1e18+1;
    il LL rd()
    {
        re LL x=0,w=1;re char ch=0;
        while(ch<'0'||ch>'9') {if(ch=='-') w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
        return x*w;
    }
    int n;
    LL a[2][10],k,b[2][M],t[2];
    il void dfs(int x,int o,LL s)
    {
      if(a[x][o+1]) dfs(x,o+1,s);
      LL ss=s;
      while(inf/a[x][o]>=ss&&ss>0)
        {
          ss*=a[x][o];
          b[x][++t[x]]=ss;
          if(a[x][o+1]) dfs(x,o+1,ss);
        }
    }
    
    int main()
    {
      n=rd();
      for(int i=1;i<=n;i++) a[i&1][(i+1)>>1]=rd();
      if(n>1) dfs(0,1,1);
      dfs(1,1,1);
      sort(b[0]+1,b[0]+t[0]+1),sort(b[1]+1,b[1]+t[1]+1);
      b[0][0]=b[1][0]=1;
      k=rd();
      LL l=0,r=inf,ans=0;
      while(l<=r)
        {
          LL mid=(l+r)>>1,kk=1;
          for(int i=0,j=t[1];i<=t[0];i++)
            {
              while(j>=0&&(b[0][i]*b[1][j]<0||b[0][i]*b[1][j]>inf||b[0][i]*b[1][j]>=mid)) --j;
              kk+=j+1;
            }
          if(kk<=k) ans=mid,l=mid+1;
          else r=mid-1;
        }
      cout<<ans;
      //hehhe
      return 0;
    }
    
    
  • 相关阅读:
    NYOJ41三个数从小到大排序
    HDUOJ2115I Love This Game
    NYOJ56阶乘因式分解(一)
    NYOJ65另一种阶乘问题
    HDUOJ1234开门人和关门人
    NYOJ74小学生算术
    NYOJ11奇偶数分离
    HDUOJ3980取模运算
    HDUOJ2014 青年歌手大奖赛_评委会打分
    HDUOJ1860 统计字符
  • 原文地址:https://www.cnblogs.com/smyjr/p/9690962.html
Copyright © 2020-2023  润新知