HDOJ 6069 素数筛
链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6069
题意:
就是题目中的公式
题解:
这个题公式很好推 d(nk) = (kc1 + 1)(kc2 + 1):::(kcm + 1)。
就是不能直接暴力算,需要利用区间素数筛
枚举不超过根号r的所有质数p,再枚举区间[l; r] 中所有p 的倍数,将其分解质因数。
我开始还用了map存了,超时,换成vector继续超时,最后不存直接算 总算过了
stl真的很耗时啊 以后遇到这种1e6的能不存就不存了
代码:
31 const ll mod = 998244353; 32 33 ll num[MAXN]; 34 ll ans[MAXN]; 35 bool is_prime[MAXN]; 36 VI v[MAXN]; 37 ll a, b, k; 38 39 void work() { 40 for (ll i = 0; i <= b - a; i++) num[i] = i + a, ans[i] = 1; 41 for (ll i = 0; i*i <= b; i++) is_prime[i] = true; 42 for (ll i = 2; i*i <= b; i++) if (is_prime[i]) { 43 for (ll j = 2 * i; j*j <= b; j += i) is_prime[j] = false; 44 for (ll j = max(2LL, ((a + i - 1) / i)*i); j <= b; j += i) { 45 int sum = 0; 46 while (num[j - a] % i == 0) num[j - a] /= i, sum++; 47 ans[j - a] = (ans[j - a] * (k*sum + 1)) % mod; 48 } 49 } 50 for (ll i = a; i <= b; i++) if (num[i - a] != 1) ans[i - a] = (ans[i-a]*(k + 1)) % mod; 51 ll ret = 0; 52 for (ll i = a; i <= b; i++) ret = (ret + ans[i - a]) % mod; 53 cout << ret << endl; 54 } 55 56 int main() { 57 ios::sync_with_stdio(false), cin.tie(0); 58 int T; 59 cin >> T; 60 while (T--) { 61 cin >> a >> b >> k; 62 work(); 63 } 64 return 0; 65 }