BZOJ 3181 BROJ

像我这种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
",i*p);return;}
    }
    printf("0
");
}
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
");
    else printf("%lld
",ans);
}
int main()
{
    scanf("%lld%lld",&k,&p);
    get_table();
    if (p>1000) work1();
    else work2();
    return 0;
}
原文地址:https://www.cnblogs.com/ziliuziliu/p/6069206.html