#include 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 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; }