zoukankan      html  css  js  c++  java
  • 大区间素数筛选 POJ2689

    题意:

    给一个区间[L,U],(1<=L< U<=2,147,483,647),U-L<=1000000,求出[L,U]内距离近期和距离最远的素数对。


    因为L,U都小于2^32,所以区间内的合数的最小质因子必定小于2^16,所以先筛出2^16以内的素数,用筛出来的素数去筛[L,U]内的合数。然后把[L,U]内的素数保存下来,再搜索近期和最远的素数对就可以。注意两整数相乘可能溢出32位,注意对1的推断。


    代码:

    #include <cstdlib>
    #include <cctype>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #include<climits>
    #include <algorithm>
    #include <vector>
    #include <string>
    #include <iostream>
    #include <sstream>
    #include <map>
    #include <set>
    #include <queue>
    #include <stack>
    #include <fstream>
    #include <numeric>
    #include <iomanip>
    #include <bitset>
    #include <list>
    #include <stdexcept>
    #include <functional>
    #include <utility>
    #include <ctime>
    using namespace std;
    
    #define PB push_back
    #define MP make_pair
    
    #define REP(i,x,n) for(int i=x;i<(n);++i)
    #define FOR(i,l,h) for(int i=(l);i<=(h);++i)
    #define FORD(i,h,l) for(int i=(h);i>=(l);--i)
    #define SZ(X) ((int)(X).size())
    #define ALL(X) (X).begin(), (X).end()
    #define RI(X) scanf("%d", &(X))
    #define RII(X, Y) scanf("%d%d", &(X), &(Y))
    #define RIII(X, Y, Z) scanf("%d%d%d", &(X), &(Y), &(Z))
    #define DRI(X) int (X); scanf("%d", &X)
    #define DRII(X, Y) int X, Y; scanf("%d%d", &X, &Y)
    #define DRIII(X, Y, Z) int X, Y, Z; scanf("%d%d%d", &X, &Y, &Z)
    #define OI(X) printf("%d",X);
    #define RS(X) scanf("%s", (X))
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MS1(X) memset((X), -1, sizeof((X)))
    #define LEN(X) strlen(X)
    #define F first
    #define S second
    #define Swap(a, b) (a ^= b, b ^= a, a ^= b)
    #define Dpoint  strcut node{int x,y}
    #define cmpd int cmp(const int &a,const int &b){return a>b;}
    
     /*#ifdef HOME
        freopen("in.txt","r",stdin);
        #endif*/
    const int MOD = 1e9+7;
    typedef vector<int> VI;
    typedef vector<string> VS;
    typedef vector<double> VD;
    typedef long long LL;
    typedef pair<int,int> PII;
    //#define HOME
    
    int Scan()
    {
    	int res = 0, ch, flag = 0;
    
    	if((ch = getchar()) == '-')				//推断正负
    		flag = 1;
    
    	else if(ch >= '0' && ch <= '9')			//得到完整的数
    		res = ch - '0';
    	while((ch = getchar()) >= '0' && ch <= '9' )
    		res = res * 10 + ch - '0';
    
    	return flag ? -res : res;
    }
    /*----------------PLEASE-----DO-----NOT-----HACK-----ME--------------------*/
    #define MAXN 100000
    int prime[MAXN];
    int vis[MAXN+5];
    int cnt;
    void getprime()
    {cnt=0;
    for(int i=2;i<=MAXN;i++)
        if(!vis[i])
    {
        prime[cnt++]=i;
        for(int j=0;j<cnt&&prime[j]<=MAXN/i;j++)
        {
            vis[prime[j]*i]=1;
            if(i%prime[j]==0)
                break;
        }
    }
    
    }
    
    int notprime[1000000+5];
    int prime2[1000000+5];
    int cnt2;
    void getprime2(int L,int U)
    {
    
        for(int i=0;i<cnt;i++)
        {   if(prime[i]>=U)
                break;
            int s=L/prime[i];
            if(s<=1)
                s=2;
            for(int j=s;(long long)prime[i]*j<=U;j++)
                if((long long )prime[i]*j>=L)
            {
                notprime[(long long )prime[i]*j-L]=1;
            }
        }
        cnt2=0;
        REP(i,0,U-L+1)
        {
            if(!notprime[i]&&(i+L)!=1&&(i+L)!=0)
                prime2[cnt2++]=i+L;
    
        }
    
    }
    
    
    
    int main()
    {getprime();
    int L,U;
    while(RII(L,U)!=EOF)
    {
        MS0(notprime);
        getprime2(L,U);
        int ans1=INT_MAX;
        int ans2=0;
        int n1,n2,f1,f2;
        if(cnt2<2)
        {
            printf("There are no adjacent primes.
    ");
            continue;
        }
        REP(i,0,cnt2-1)
        {
           if(prime2[i+1]-prime2[i]<ans1)
           {
               ans1=prime2[i+1]-prime2[i];
               n1=prime2[i];
               n2=prime2[i+1];
           }
           if(prime2[i+1]-prime2[i]>ans2)
           {
               ans2=prime2[i+1]-prime2[i];
               f1=prime2[i];
               f2=prime2[i+1];
           }
        }
        printf("%d,%d are closest, %d,%d are most distant.
    ",n1,n2,f1,f2);
    }
    
    
    
            return 0;
    }
    
    


  • 相关阅读:
    POJ 2236 Wireless Network(并查集)
    POJ 2010 Moo University
    POJ 3614 Sunscreen(贪心,区间单点匹配)
    POJ 2184 Cow Exhibition(背包)
    POJ 1631 Bridging signals(LIS的等价表述)
    POJ 3181 Dollar Dayz(递推,两个long long)
    POJ 3046 Ant Counting(递推,和号优化)
    POJ 3280 Cheapest Palindrome(区间dp)
    POJ 3616 Milking Time(dp)
    POJ 2385 Apple Catching(01背包)
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5335979.html
Copyright © 2011-2022 走看看