POJ2689 Prime Distance ——区间素数筛

14 篇文章 0 订阅
13 篇文章 0 订阅

Link

题意:

给出一个区间[l, r],找出区间内相邻的距离最近的两个素数和距离最远的两个素数1<=l<r<=2,147,483,647 区间长度不超过1,000,000

Code:

//
#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pii pair<int,int>
#define pb push_back
#define ll long long
#define LL long long
#define ld long double
#define endl '\n'
#define RE0 return 0
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)

#define int long long
const int maxn = 5e4 + 10;
const int maxm = 1e6 + 10;
const int INF = 0x3f3f3f3f;
const int dx[] = {0,0,-1,1,1,1,-1,-1};
const int dy[] = {1,-1,0,0,1,-1,1,-1};
const int P = 1e9 + 7;    //998244353
LL power(LL a, LL b) {
    LL ans = 1 % P;
    for (; b; b >>= 1) {
        if (b & 1)  ans = ans * a % P;
        a = a * a % P;
    }
    return ans;
}
int prime[maxn];
bool vis[maxn];
bool vis2[maxm];
int prime2[maxm];
int tot;
void init(int n){
    for(int i = 0; i <= n; i++) {
        prime[i] = 0;
        vis[i] = 0;
    }
    for(int i = 2; i <= n; i++) {
        if (!vis[i]) {
            prime[++prime[0]] = i;
        }
        for (int j = 1; j<=prime[0] && i*prime[j]<=maxn; j++) {
            vis[i*prime[j]] = 1;
            if (i % prime[j] == 0) {
                break;
            }
        }
    }
    tot = prime[0];
}
void solve() {
    int l, r;
    cin >> l >> r;
//     if(l == 1) l++;
    for(int i = 0; i <= (int)1e6; i++) vis2[i] = 0;
    for(int i = 1; i <= tot; i++) {
        int a = (l-1)/prime[i] + 1;
        int b = r / prime[i];
        for(int j = a; j <= b; j++)
            if(j > 1)
            vis2[prime[i]*j-l] = 1;
    }
    int t = 0;
    for(int i = 0; i <= (int)r - l; i++) {
        if(!vis2[i])
            prime2[++t] = i + l;
    }
    if(t < 2) {
        printf("There are no adjacent primes.\n");
        return;
    }
    int minn = INF, maxx = -1;
    int c1, c2, d1, d2;
    for(int i = 1; i < t; i++) {
        if(prime2[i+1] - prime2[i] < minn) {
            c1 = prime2[i];
            c2 = prime2[i+1];
            minn = prime2[i+1] - prime2[i];
        }
        if(prime2[i+1] - prime2[i] > maxx) {
            d1 = prime2[i];
            d2 = prime2[i+1];
            maxx = prime2[i+1] - prime2[i];
        }
    }
    printf("%d,%d are closest, %d,%d are most distant.\n", c1,c2,d1,d2);
    for(int i = 0; i <= t; i++) prime2[i] = 0;
    
    
}
signed main() {
//     ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//    int T; scanf("%d", &T); while(T--)
//    freopen("1.txt","r",stdin);
//    freopen("2.txt","w",stdout);
    init((int)maxn - 10);
    int T; cin >> T; while(T--)
        solve();
    RE0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值