You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

73 lines
1.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
/**
测试用例:
10 20 3
答案:
7
*/
//欧拉筛
int primes[N], cnt; // primes[]存储所有素数
bool st[N]; // st[x]存储x是否被筛掉
void get_primes(int n) {
for (int i = 2; i <= n; i++) {
if (!st[i]) primes[cnt++] = i;
for (int j = 0; primes[j]*i <= n; j++) {
st[primes[j] * i] = true;
if (i % primes[j] == 0) break;
}
}
}
//并查集数组
int fa[N];
//要深入理解这个递归并压缩的过程
int find(int x) {
if (fa[x] != x) fa[x] = find(fa[x]);
return fa[x];
}
//加入家族集合中
void join(int c1, int c2) {
int f1 = find(c1), f2 = find(c2);
if (f1 != f2)fa[f1] = f2;
}
//读入一个开始和结束a:开始b结束
int a, B, p, ans;
int main() {
//读入
cin >> a >> b >> p;
//并查集初始化
for (int i = a; i <= b; i++) fa[i] = i;
//筛出b以内的所有素数
get_primes(b);
//遍历筛出的质数表找到每一个大于等于p的质数然后把这个质数在y范围内的倍数找出来并加入到动态数组v中
for (int i = 0; i < cnt; i++) {
if (primes[i] >= p) {
//将具有公共质数因子的数放到一个数组v中
vector<int> v;
for (int j = 1; j * primes[i] <= b; j++)//找出质数倍数
if (j * primes[i] >= a && j * primes[i] <= b)
v.push_back(j * primes[i]);
//把数组v中的元素进行并查集关联
for (int j = 1; j < v.size(); j++)
join(v[j - 1], v[j]);
}
}
//并查集个数
for (int i = a; i <= b; i++) if (fa[i] == i) ans++;
//输出
cout << ans << endl;
return 0;
}