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 }

 

posted @ 2017-08-03 21:05  Flowersea  阅读(161)  评论(0编辑  收藏  举报