1.题目描述:点击打开链接
2.解题思路:本题要求找在区间[L,R]中素因子只有一个且自身不是素数的数,这实际上就是找素因子的幂次大于1的数在该区间中有几个。可以利用前缀和的思想,用cal(k)表示不超过k的这样的数有几个,那么最终的答案就是cal(R)-cal(L-1)。而cal()函数可以通过逐一尝试素数计算最大幂次来得到。当p>sqrt(k)时即可停止枚举。
注意要用long long输入。
3.代码:
#define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<algorithm> #include<string> #include<sstream> #include<set> #include<vector> #include<stack> #include<map> #include<queue> #include<deque> #include<cstdlib> #include<cstdio> #include<cstring> #include<cmath> #include<ctime> #include<functional> using namespace std; typedef long long ll; #define MAXN 1000000+10 int vis[MAXN]; vector<int>primes; void init() { memset(vis, 0, sizeof(vis)); int m = sqrt(MAXN + 0.5); for (int i = 2; i < m;i++) for (int j = i*i; j < MAXN; j += i) vis[j] = 1; for (int i = 2; i < MAXN;i++) if (!vis[i]) primes.push_back(i); } int cal(ll k) { int m = sqrt((double)k + 0.5); int cnt = 0; int len = primes.size(); for (int i = 0; i < len; i++) { if (primes[i]>m)break; cnt += log((double)k) / log(primes[i]) - 1; } return cnt; } int main() { freopen("t.txt", "r", stdin); int T; init(); cin >> T; while (T--) { ll a, b; cin >> a >> b; int s = cal(a-1), t = cal(b); cout << t - s << endl; } return 0; }
时间: 2024-11-09 01:41:15