zoukankan      html  css  js  c++  java
  • UVA10140PrimeDistance题解--质数/技巧

    题目链接

    https://www.luogu.org/problemnew/show/UVA10140

    分析

    (L,R)都很大,显然不能直接筛出(L,R)区间中的质数,这里需要一个结论

    结论

    任何一个合数(N)必定含有一个小于等于(sqrt N)的质因子

    证明

    反证法,若所有质因子都大于(sqrt N),那么无论怎么组合显然都大于(N)

    于是通过这个结论筛出([2,sqrt R]),中的所有素数,把它们看作质因子筛出([L,R])中的所有合数

    注意如果(L)(1)的话需要注意,不要把(1)标记为质数,对拍了好久才发现...真坑啊

    代码

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cctype>
    #include <queue>
    #include <cmath>
    #define ll long long 
    #define ri register int 
    using std::min;
    using std::max;
    template <class T>inline void read(T &x){
    	x=0;int ne=0;char c;
    	while(!isdigit(c=getchar()))ne=c=='-';
    	x=c-48;
    	while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
    	x=ne?-x:x;return ;
    }
    const int maxn=1500005;
    const int inf=0x7fffffff;
    int l,r;
    bool ok[maxn],vis[50000];
    int prime[50000],tot=0;
    inline void get_prime(){
    	int lim=(int)(std::sqrt(1.0*inf+0.5));
    	//printf("%d
    ",lim);
    	for(ri i=2;i<=lim;i++){
    		if(!vis[i]){
    			vis[i]=1;
    			prime[++tot]=i;		
    		}
    		for(ri j=1;j<=tot&&1ll*prime[j]*i<=lim;j++){
    			vis[i*prime[j]]=1;	
    			if(i%prime[j]==0)break;
    		}
    	}
    	return ;
    }
    inline void solve(int n){
    	int lim=(int)(std::sqrt(1.0*n+0.5));
    	memset(ok,0,sizeof(ok));
    	int o=1;
    	while(prime[o]<=lim&&o<=tot){
    		for(ri k=l/prime[o];k<=r/prime[o];k++){
    			if(k==1||k==0)continue;
          /*注意k=1及k=0都是不合法的情况*/
    			ok[k*prime[o]-l]=1;
          /*左移L位以储存结果*/
    		}
    		o++;
    	}
    	return ;
    }
    int main(){
    	freopen("dat.in","r",stdin);
    	freopen("wa.out","w",stdout);
    	get_prime();
    	while(scanf("%d %d",&l,&r)!=EOF){	
    	    /*注意!!!*/	
    		if(l==1)l=2;                
    		//注意!!! 1不是质数 
    		int lnum,lst=-inf,xans=-1,ians=inf; 
    		int a,b,c,d;
    		solve(r);
    		for(ri i=0;i<=r-l;i++){
    			if(!ok[i]){
    				if(lst!=-inf){
    					//xans=max(xans,i-lst);
    					if(i-lst>xans){
    						c=lst,d=i;
    						xans=i-lst;
    					}
    					if(i-lst<ians){
    						a=lst,b=i;
    						ians=i-lst;
    					}
    					//ians=min(ians,i-lst);
    				}
    				lst=i;
    			}
    		}
    		if(xans==-1){
    			puts("There are no adjacent primes.");
     		}
    		else{
    			printf("%d,%d are closest, %d,%d are most distant.
    ",a+l,b+l,c+l,d+l);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    SecureCRT
    MySQL
    流式计算概述
    WEB加密算法
    drop、truncate和delete的区别
    JVM参数
    HTTP1.0与HTTP1.1区别
    HTTP请求方法
    Java查看JVM转态的命令总结
    go二次更新
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/9627513.html
Copyright © 2011-2022 走看看