像我这种SB还是早点退役。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1000050 #define inf 1000000000 using namespace std; long long k,p,prime[maxn],cnt=0,tab[maxn],lim,regis,kr=0; bool vis[maxn]; void get_table() { tab[1]=1; for (long long i=2;i<=maxn-50;i++) { if (!vis[i]) { tab[i]=i; prime[++cnt]=i; if (i==p) lim=cnt; } for (long long j=1;j<=cnt && i*prime[j]<=maxn-50;j++) { vis[i*prime[j]]=true;tab[i*prime[j]]=prime[j]; if (!(i%prime[j])) break; } } } void dfs(long long x,long long ret,long long tag) { if (ret>regis) return; if (x==lim) { kr+=regis/ret*tag; return; } dfs(x+1,ret,tag); dfs(x+1,ret*prime[x],-tag); } long long check(long long x) { regis=x/p;kr=0; dfs(1,1,1); return kr; } void work1() { k--; long long ret=0; for (long long i=1;i<=maxn-50;i++) { if (i*p>inf) break; if (tab[i]>=p) ret++; if (ret==k) {printf("%lld\n",i*p);return;} } printf("0\n"); } void work2() { long long l=1,r=inf,ans=-1; while (l<=r) { long long mid=l+r>>1,ret=check(mid); if (ret>=k) {ans=mid;r=mid-1;} else l=mid+1; } if (ans==-1) printf("0\n"); else printf("%lld\n",ans); } int main() { scanf("%lld%lld",&k,&p); get_table(); if (p>1000) work1(); else work2(); return 0; }