zoukankan      html  css  js  c++  java
  • 【JZOJ3188】找数【数论,数学】

    题目大意:

    题目链接:https://jzoj.net/senior/#main/show/3188
    找出第NN个最小素因子是PP的正整数。


    思路:

    sto XXY orzcolor{red} exttt{sto XXY orz}

    sto XXY orzcolor{blue} exttt{sto XXY orz}

    sto XXY orzcolor{green} exttt{sto XXY orz}

    sto XXY orz(再加一遍XD)color{white} exttt{sto XXY orz(再加一遍XD)}

    重要的事情说三遍。


    这道题n109nleq 10^9
    XXYdalaodalao给出了110frac{1}{10}常数的暴力。
    然后就过了。
    首先特判n=1n=1,显然输出1。
    然后特判n>1n>1p2>109p^2>10^9,显然输出0。
    接下来依次特判p=2,p=3,p=5,p=7,p=11p=2,p=3,p=5,p=7,p=11。最坏情况下p=5p=51092pfrac{10^9}{2p}的复杂度。
    然后剩下的就是p>11p>11的了。枚举pp的倍数,判断是否成立。
    时间复杂度O(108+O(10^8+某些常数))。鉴于JZOJ评测机很好,416ms416ms跑过了。


    代码:

    #include <cstdio>
    #define rr register
    using namespace std;
    typedef long long ll;
    
    const int MAXN=1e9;
    const int Psum=35000;
    int n,p,cnt,k,prime[Psum],v[Psum];
    void find(int maxn)
    {
    	for (int i=2;i<=maxn;i++)
    	{
    		if (!v[i])
    		{
    			v[i]=i;
    			prime[++cnt]=i;
    		}
    		for (int j=1;j<=cnt;j++)
    		{
    			if (prime[j]*i>maxn) break;
    			if (prime[j]>v[i]) break;
    			v[i*prime[j]]=prime[j];
    		}
    	}
    }
    
    int check(int x)
    {
    	for (int i=1;i<k;i++)
    		if (!(x%prime[i])) return 0;
    	return 1;
    }
    
    int main()
    {
    	scanf("%d%d",&n,&p);
    	if (n==1)
    	{
    		printf("%d",p);
    		return 0;
    	}
    	if (n>1&&(ll)p*(ll)p>MAXN)
    	{
    		printf("0");
    		return 0;
    	}
    	if (p==2)
    	{
    		if (n*p<=MAXN) printf("%d",n*p);
    			else printf("0");
    		return 0;
    	}
    	if (p==3)
    	{
    		ll x=3+(ll)(n-1)*6;
    		if (x<=MAXN) printf("%lld",x);
    			else printf("0");
    		return 0;
    	}
    	if (p==5)
    	{
    		for (rr int i=p;i<=MAXN;i+=2*p)
    			if (i%3)
    			{
    				n--;
    				if (!n)
    				{
    					printf("%d",i);
    					return 0;
    				}
    			}
    		printf("0");
    		return 0;
    	}
    	if (p==7)
    	{
    		for (rr int i=p;i<=MAXN;i+=2*p)
    			if (i%3&&i%5)
    			{
    				n--;
    				if (!n)
    				{
    					printf("%d",i);
    					return 0;
    				}
    			}
    		printf("0");
    		return 0;
    	}
    	if (p==11)
    	{
    		for (rr int i=p;i<=MAXN;i+=2*p)
    			if (i%3&&i%5&&i%7)
    			{
    				n--;
    				if (!n)
    				{
    					printf("%d",i);
    					return 0;
    				}
    			}
    		printf("0");
    		return 0;
    	}
    	find(Psum);
    	for (k=1;k<=cnt;k++)
    		if (prime[k]==p) break;
    	for (rr int i=p;i<=MAXN;i+=2*p)
    		if (check(i))
    		{
    			n--;
    			if (!n)
    			{
    				printf("%d",i);
    				return 0;
    			}
    		}
    	printf("0");
    	return 0;
    }
    
  • 相关阅读:
    luogu P1833 樱花 看成混合背包
    luogu P1077 摆花 基础记数dp
    luogu P1095 守望者的逃离 经典dp
    Even Subset Sum Problem CodeForces
    Maximum White Subtree CodeForces
    Sleeping Schedule CodeForces
    Bombs CodeForces
    病毒侵袭持续中 HDU
    病毒侵袭 HDU
    Educational Codeforces Round 35 (Rated for Div. 2)
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998263.html
Copyright © 2011-2022 走看看