zoukankan      html  css  js  c++  java
  • bzoj3181: [Coci2012]BROJ

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 using namespace std;
     7 int n,p,top,list[105],bin[18],num[200005],ans,l,r,mid;
     8 bool bo[15000005],vis[105];
     9 int lowbit(int x){return x&(-x);}
    10 int work(int x,int y){
    11     long long fuckpps=1;
    12     for (int i=1;i<=top;i++){
    13         if (x&bin[i-1]) fuckpps=fuckpps*list[i];
    14         if (fuckpps>1e9) return 0;
    15     }
    16     return y/fuckpps*(num[x]%2==0?1:-1);
    17 }
    18 bool check(int x){
    19     x/=p;
    20     int sum=0;
    21     for (int i=0;i<bin[top];i++){sum+=work(i,x);}
    22     return sum>=n;
    23 }
    24 int main(){
    25     int x;
    26     cin>>n>>p;
    27     if (p>=69){
    28         x=1000000000/p;
    29         memset(bo,1,sizeof(bo)); bo[1]=1; int cnt=1;
    30         if (n==1){
    31             printf("%d
    ",p);
    32             return 0;
    33         }
    34         for (int i=2;i<=x;i++){
    35             if (bo[i]){
    36                 if (i<p) for (long long j=1LL*i*i;j<=x;j+=i) bo[j]=0;
    37                 else{
    38                     cnt++; if (cnt==n){printf("%d
    ",i*p);return 0;}
    39                 }
    40             }
    41         }
    42         if (cnt<n) puts("0");
    43         return 0;
    44     }
    45     top=0; memset(vis,0,sizeof(vis));
    46     for (int i=2;i<p;i++){
    47         if (!vis[i]){
    48             list[++top]=i;
    49         }
    50         for (int j=1;j<=top;j++){
    51             if (i*list[j]>=p) break;
    52             vis[i*list[j]]=1;
    53             if (i%list[j]==0) break; 
    54         }
    55     }
    56     bin[0]=1; for (int i=1;i<=top;i++) bin[i]=bin[i-1]<<1;
    57     for (int i=1;i<bin[top];i++) num[i]=num[i-lowbit(i)]+1;
    58     ans=0; l=1,r=1e9;
    59     while (l<=r){
    60         mid=(l+r)>>1;
    61         if (check(mid)) ans=mid,r=mid-1;
    62         else l=mid+1;
    63     }
    64     printf("%d
    ",ans);
    65     return 0;
    66 }
    View Code

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3181

    题意:求最小质因子等于p的第n小的正整数(恰好有n-1个最小质因子等于p且比它
    小的正整数)。p一定是质数。若答案超过10^9则输出0。 

    做法:当p>=69时,10^9/p可以接受线性算法,我们就找到1~10^9/p中最小质因子>=p的个数,我们可以用筛法实现,具体见代码,比较神奇。

    当p<=61时,我们考虑二分答案x,然后容斥即可,复杂度为O(min(10^9/p,2^(小于p的质数个数)LogL))。

  • 相关阅读:
    【HDOJ】2774 Shuffle
    【POJ】2170 Lattice Animals
    【POJ】1084 Square Destroyer
    【POJ】3523 The Morning after Halloween
    【POJ】3134 Power Calculus
    【Latex】如何在Latex中插入伪代码 —— clrscode3e
    【HDOJ】4801 Pocket Cube 的几种解法和优化
    【HDOJ】4080 Stammering Aliens
    【HDOJ】1800 Flying to the Mars
    SQL语法
  • 原文地址:https://www.cnblogs.com/OYzx/p/5999301.html
Copyright © 2011-2022 走看看