线性筛+区间枚举

来源:互联网 发布:南通java培训机构 编辑:程序博客网 时间:2024/06/11 09:49

题目大意:给出区间a,b求区间内素数的个数

但是a,b非常大

#include<iostream>#include<cstdio>#include<cstring>using namespace std;typedef long long LL;const int N = 1e6 + 5;bool vis[N], visab[N];int prime[N], cnt = 0;void is_prime(){memset(vis, 0, sizeof(vis));vis[1] = 1;for (int i = 2; i<N; i++){if (!vis[i]){prime[cnt++] = i;}for (int j = 0; j < cnt; j++) {if (i*prime[j] > N)break;vis[i*prime[j]] = 1;if (i%prime[j] == 0)break;//如果i能被已有的素数整数则跳出,避免重复标记}}}int main(){//freopen("Text.txt", "r", stdin);int t;cin >> t;is_prime();for (int kase = 1; kase <= t; kase++){LL a, b;scanf("%lld%lld", &a, &b);int count = 0;if (b <= N - 1){for (LL i = a; i <= b; i++){if (!vis[i])count++;}}else{memset(visab, 0, sizeof(visab));for (int i = 0; i<cnt&&prime[i] <= b; i++){LL k = a / prime[i];if (k*prime[i]<a)k++;//求第一个使k*prime[i]>=a的倍数kfor (LL j = k*prime[i]; j <= b; j += prime[i]){visab[j - a] = 1;//区间左移a}}for (LL i = a; i <= b; i++){if (!visab[i - a])count++;}}printf("Case %d: %d\n", kase, count);}}