zoukankan      html  css  js  c++  java
  • Prime Distance(求区间素数)

    传送门

    这道题,其实思路很简单,但是。。坑是很多的


    思路

    我们发现L,R很大,但是区间只有1e6。

    我们知道,R必定包含一个不超过根号R的质因子,所以只需要用筛法求出2~根号R的所有质数,对于每个质数p,把[L,R]中能被p整除的数标记,即标记i*p为合数,最终[L,R]中没被标记的就是质数,一个一个挨着比较就好

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <iostream>
    #include <algorithm>
    #define N 700003
    #define LL long long
    #define INF 2100000000
    using namespace std;
    int not_prime[N],he[1000050];
    int prime[N];
    int tot=0;
    void work(int n)
    {
        for(LL i=2;i<=n;++i)
        {
            if(!not_prime[i])
            prime[++tot]=i;
            for(LL j=1;j<=tot&&prime[j]*i<=n;++j)
            {
                not_prime[prime[j]*i]=1;
                if(i%prime[j]==0)break;
            }
        }
    }
    int main()
    {
        LL l,r;
        work(50000);
        while(scanf("%lld%lld",&l,&r)!=EOF)
        {
            if(l==1)l=2;
            memset(he,0,sizeof(he));
            for(int i=1;i<=tot;++i)
            {
                if(prime[i]*prime[i]>r) break;
                int a=l/prime[i];
                a=max(2,a); 
                int b=r/prime[i];
                for(int j=a;j<=b;++j)
                   if(j*prime[i]-l>=0)he[j*prime[i]-l]=1;
            }
            LL front=-INF,minn=INF,maxx=-INF;
            int ansmax1=0,ansmax2=0,ansmin1=0,ansmin2=0;
            for(LL i=l;i<=r;++i)//用long long,不然会RE!!! 
            {
                if(he[i-l])continue;
                if(front==-INF){front=i;continue;} 
                else
                {
                    if(i-front<minn)ansmin1=front,ansmin2=i,minn=i-front;
                    if(i-front>maxx)ansmax1=front,ansmax2=i,maxx=i-front;
                    front=i;
                 }
            } 
            if(ansmax2==0)printf("There are no adjacent primes.
    ");
            else printf("%d,%d are closest, %d,%d are most distant.
    ",ansmin1,ansmin2,ansmax1,ansmax2);
        }
        return 0;
    }
    poj2689

    然后这道题卡了我很久。。真的卡了我很久,不是TLE就是RE。

    有两个很大的坑点可能只对于我来说吧

    1.RE:L到R的范围是2^31,很容易爆int

    如果在最后的循环里这样写

     for(int i=l;i<=r;++i)
    View Code

    就RE。。。

    所以应该用LL


    2.TLE

    我原来筛[L,R]间的合数是这样写的

    for(int i=1;i<=tot;++i)
            {
                if(prime[i]*prime[i]>r) break;
                int j=l/prime[i];
                if(j<2)j=2;
                for(;j*prime[i]<=r;++j)
                   if(j*prime[i]-l>=0)he[j*prime[i]-l]=1;
            }
    View Code

    然后应该这么写

            for(int i=1;i<=tot;++i)
            {
                if(prime[i]*prime[i]>r) break;
                int a=l/prime[i];
                a=max(2,a); 
                int b=r/prime[i];
                for(int j=a;j<=b;++j)
                   if(j*prime[i]-l>=0)he[j*prime[i]-l]=1;
            }
    View Code

    把prime[i]*j放在循环中会TLE。。(污秽之语)


    这道题,真的说不出话。。

  • 相关阅读:
    类UNIX系统
    wxpython
    新闻
    游戏公司排名
    游戏网站
    3D打印
    python程序报"iccp known incorrect srgb profile" 警告
    python命令行退出
    plc和嵌入式的区别
    要理解互联网的变化轨迹,唯一的方法是弄清背后的规律。“在线”这个所有人既熟悉又陌生的词语,既是常识,也是我一系列想法的核心。
  • 原文地址:https://www.cnblogs.com/yyys-/p/11222592.html
Copyright © 2011-2022 走看看