高端算法 求a,b之间素数的个数

先给出一个sieve筛素数的模板:

 

poj  2689 Prime Distance     筛选法求给定区间内的素数

 
#include<stdio.h>
#include<math.h>
#define  maxn 1024000 
int L,U; 
long long p[maxn],sz; 
long long flag[maxn];
void sieve(long long L,long long U)
{
        long long d=U-L+1,i,limit=(long long)sqrt((double)U);
        
                  for(i=0;i<d;i++)      
                          flag[i]=1;
                  for(i=L&0x1;i<d;i+=2) 
                          flag[i]=0;
                  for(i=3;i<=limit;i+=2)
                  {
                          if(i>L&&flag[i-L]==0)
                                  continue;
                          
                          int j=L/i*i;
                          if(j<L)   j+=i;
                          if(j==i)  j+=i; j=j-L;
                          for(;j<d;j+=i)  
                                  flag[j]=0;
                  }
                  if(L<=1)  flag[1-L]=0;
                  if(L<=2)  flag[2-L]=1;
                  sz=0;
                  for(i=0;i<d;i++)
                          if(flag[i]==1)
                                  p[++sz]=i+L;
                          
}

int main()
{
        long long min;
        long long i,n,j,k,c,max;
        while(scanf("%lld%lld",&c,&n)!=EOF)
        { 
                min=999999999;
                max=0;
                sieve(c,n);
                if(sz==1||sz==0)  {printf("There are no adjacent primes.\n");continue;}
                for(i=2;i<=sz;i++)
                {
                        if(max<(p[i]-p[i-1]))
                        { max=p[i]-p[i-1];
                        j=i;
                        }
                        if(min>(p[i]-p[i-1]))
                        {  min=p[i]-p[i-1];
                        k=i;
                        }
                }
                
                printf("%lld,%lld are closest, %lld,%lld are most distant.\n",p[k-1],p[k],p[j-1],p[j]);
        }
        return 0;
}
重点是如果n很大很大呢。我只有模板,并不懂为什么,我想静静

统计a,b之间素数的个数 a,b<=1e9;

代码:那个大神能看到给我讲讲那就最好了,多谢

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <map>
#include <set>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cassert>
#include <unordered_map>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

#define ff(i, n) for (int i = 0, END = (n); i < END; i ++)
#define fff(i, n, m) for (int i = (n), END = (m); i <= END; i ++)
#define dff(i, n, m) for (int i = (n), END = (m); i >= END; i --)
#define travel(e, u) for (int e = first[u], v = vv[first[u]]; ~e; e = nxt[e], v = vv[e])
#define bit(n) (1ll << (n))
#define mid ((l&r) + ((l^r)>>1))
#define debug(x) cout << "Line " << __LINE__ << ": " << #x << " = " << x << endl;

#define ls (rt<<1)
#define rs (ls|1)
#define lson l, m, ls
#define rson m + 1, r, rs

template<typename T>
bool read(T & x)
{
    char ch;
    bool neg = false;

    do
    {
        ch = getchar();
    }
    while (!isdigit(ch) && ch != '-' && ch != -1);

    if (ch == -1) return false;
    if (ch == '-') neg = true;

    x = ch - '0';
    ch = getchar();
    while('0' <= ch && ch <= '9')
    {
        x = x * 10 + (ch - '0');
        ch = getchar();
    }

    if (neg) x = -x;
    return true;
}

bool read(char * str)
{
    return scanf("%s", str) == 1;
}
bool read(double & v)
{
    return scanf("%lf", &v) == 1;
}
template<typename A, typename B>
bool read(A & a, B & b)
{
    return read(a) && read(b);
}

template<typename T>
void print(T x)
{
    if (x < 0)
    {
        if (-x == x)
        {
            cout << x << endl;
            return;
        }
        putchar('-');
        print(-x);
    }
    else if (x < 10)
    {
        putchar(x + '0');
    }
    else
    {
        print(x / 10);
        putchar(x % 10 + '0');
    }
}

template<typename T>
void println(T x)
{
    print(x);
    putchar('\n');
}

void work();
int main()
{
    work();
    return 0;
}

/********************For Get********************/

/* with c++ 11 */
int v[80000], len;

int binary_find(int t)
{
    int l = 0, r = len - 1;

    while (l <= r)
    {
        int m = mid;
        if (v[m] >= t)
        {
            l = m + 1;
        }
        else
        {
            r = m - 1;
        }
    }
    return l;
}

int count_of_primes_under(int n)
{
    if (n <= 0) return 0;
    int r = int(sqrt(double(n)));

    len = 0;
    fff (i, 1, r)
    {
        v[len ++] = n / i;
    }
    dff (i, n / r - 1, 1)
    {
        v[len ++] = i;
    }

    unordered_map <int, int> s;
    ff (i, len)
    {
        s[v[i]] = v[i] - 1;
    }
    fff (p, 2, r)
    {
        if (s[p] > s[p - 1])
        {
            int sp = s[p - 1];
            int end_pos = binary_find(p * p);
            ff (i, end_pos)
            {
                s[v[i]] -= (s[v[i] / p] - sp);
            }
        }
    }
    return s[n];
}

void work()
{
    int a, b;
    while(scanf("%d%d", &a, &b) == 2)
    {
        assert(1 <= a);
        assert(a <= b);
        assert(b <= int(1e9));
        println(count_of_primes_under(b) - count_of_primes_under(a - 1));
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值