Newcoder 40 E.珂朵莉的數論題(數論+二分+容斥)
阿新 • • 發佈:2018-12-16
Description
珂朵莉想求:
第小的正整數使得其最小的質因數為質數,即正好有個之內的正整數滿足其最小的質因數為質數。
若答案超過則輸出。
Input
第一行兩個正整數
output
輸出一個整數表示答案
Sample Input
2 3
Sample Output
9
Solution
分類討論,若,線性篩出中所有不以小於的素數為因子的數即可;若,取適合的使得小於的素數不太多,二分答案,容斥求出中不以小於的素數為因子的數即可,取左右即可
Code
#include<cstdio> #include<vector> using namespace std; const int maxn=16700000,S=60; vector<int>p; bool mark[maxn],vis[66]; void prime(int n) { for(int i=2;i<=n;i++) if(!vis[i]) { p.push_back(i); for(int j=2*i;j<=n;j+=i)vis[j]=1; } } int check(int n,int m) { int M=1<<m,ans=n; for(int i=1;i<M;i++) { int num=0,temp=n; for(int j=0;j<m;j++) if((i>>j)&1) num++,temp/=p[j]; if(num&1)ans-=temp; else ans+=temp; } return ans; } int main() { int x,y; scanf("%d%d",&x,&y); if(y>=S) { int n=1e9/y; if(n<x)printf("0\n"); else { for(int i=2;i<y;i++) if(!mark[i]) for(int j=i;j<=n;j+=i)mark[j]=1; int res=0; for(int i=1;i<=n;i++) if(!mark[i]) { res++; if(res==x) { printf("%d\n",i*y); break; } } if(res<x)printf("0\n"); } } else { prime(S); int m; for(int i=0;i<p.size();i++) if(p[i]==y) { m=i; break; } int l=1,r=1e9/y,mid,ans=0; while(l<=r) { mid=(l+r)/2; if(check(mid,m)>=x)ans=mid*y,r=mid-1; else l=mid+1; } printf("%d\n",ans); } return 0; }