• jzoj 3188. 【GDOI2013模拟8】找数


    Description

    找出第N个最小素因子是P的正整数。

    Input

    一行两个整数N和P(1<=N,P<=10^9),保证P是素数。

    Output

    如果结果超过10^9则输出0否则输出这个数。

    Sample Input

    输入1:

    1 2

    输入2:

    2 3

    输入3:

    1000 1000003

    Sample Output

    输出1:

    2

    输出2:

    9

    输出3:

    0

    Data Constraint

    30%的数据满足结果不超过100,000或者超过10^9;

    另外30%的数据满足P大于1000。

    Solution

    剪枝大法好啊!!!
    首先,我们可以很容易地知道,最小素因子是P的正整数一定是p的倍数。
    然后,我们可以将这个正整数k分解一下,k = p * q。
    之后,我们可以想到二分(我是想不到的。。。)
    我们二分q的值,然后在求一下1~q之间有多少个数的因数是小于q的,
    这样我们也就知道了p * 1,p * 2,p * 3,…,p * q中有多少个数的因数是小于q的(PS:p是质数)
    而求的话我们就递归容斥就可以了,枚举一下每个因数选与不选。
    一定要剪枝!!!不剪枝7000ms+,剪了枝就55ms,就55ms!(快来购买啊!)
    好啦,这样子就能AC啦~~~

    Code

    #include<cstdio>
    #define N 1000000000
    #define ll long long
    using namespace std;
    int n,pri[N>>7],tot=0,bef;
    ll k=1,p,now,l,r,mid;
    bool bz[N>>5];
    
    void ycl()
    {
    	for (int i=2;i<=p;i++)
    	{
    		if (!bz[i]) pri[++tot]=i;
    		for (int j=1;j<=tot;j++)
    		{
    			if (i*pri[j]>p) break;
    			bz[i*pri[j]]=1;
    			if (i%pri[j]==0) break;
    		}
    	}
    }
    
    void dfs(int x,ll s,int hav)
    {
    	if (x==tot || s*pri[x]>mid)
    	{
    		if (hav & 1) bef+=mid/s;
    		else bef-=mid/s;
    		return;
    	}
    	if (s*pri[x]<=mid) dfs(x+1,s*pri[x],hav+1);
    	dfs(x+1,s,hav);
    }
    
    int main()
    {
    //	freopen("find.in","r",stdin);
    //	freopen("find.out","w",stdout);
    	scanf("%d%lld",&n,&p);
    	if (n==1) return 0&printf("%lld
    ",p);
    	else if (p*p>N) return 0&puts("0");
    	ycl();
    	l=p,r=N/p+1;
    	while (l<=r)
    	{
    		mid=l+r>>1;
    		bef=mid,dfs(1,1,0);
    		bef=mid-bef;
    		if (bef<n) l=mid+1;
    		else r=mid-1;
    	}
    	if (l*p>N) puts("0");
    	else printf("%d
    ",l*p);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    【译】System.Text.Json 的下一步是什么
    渲染路径(Rendering Path):Forward、Deferred、LightPrePass、Tiled、Clustered
    前端面试汇总
    微前端建设方案
    微前端说明以及使用
    大家好,新来到贵宝地,想跟大家一起学习,一起交流,请大伙多多指教。
    Active Directroy user and computers 批量查询被Disable的user 和长时间没有登录的User
    Powershell 启动windows server
    iTerm2与oh my zsh的安装使用记录
    Linux 命令行编辑快捷键[转]
  • 原文地址:https://www.cnblogs.com/jz929/p/11817542.html
Copyright © 2020-2023  润新知