/*给出正整数n,m(n<m),则在区间[n,m]内有多少无平方因子?1<=n<=m<=10^12,m-n<=10^7 --分析:采用素数筛法:对于不超过sqrt(m)的所有素数p,筛掉区间[n,m]内p^2的倍数 --*/ #define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<string.h> using namespace std; const int maxn = 10000000+10; bool squre[maxn]; //筛去[n,m]中平方因子数 //线性复杂度的Euler素数筛法构造素数表 bool vis[maxn]; int prime[maxn]; int Euler(int n){ memset(vis, 0, sizeof(vis)); int phi = 0; for (int i = 2; i <= n; i++){ if (!vis[i]) prime[phi++] = i; //i是素数 for (int j = 0; j < phi&&i*prime[j] <= n; j++){ vis[i*prime[j]] = 1; //筛去 if (i%prime[j] == 0)break; //i是合数(当前是合法的),并且这个数已经被筛过 } } return phi; //返回素数个数 } int Eratoshtenes(int n, int m){ memset(squre, 0, sizeof(squre)); for (int i = 0; prime[i] * prime[i] <=m; i++){ int d = prime[i] * prime[i]; for (int j = 1; d*j <= m;j++) if (j*d >= n)squre[j*d-n] = 1; //筛去 } int ans = 0; for (int i = 0; i <=m - n;i++) if (!squre[i])ans++; return ans; } int main(){ int n, m; Euler(1000000);//10^6内的素数 while (~scanf("%d%d", &n, &m)){ printf("%d ", Eratoshtenes(n, m)); } return 0; }