题目链接
题意
$d(i)$表示约数函数。计算 .
其中.
思路
因为注意到其实范围不大,我们可以计算这个范围内每一个数字的答案,分开素数和非素数。
素数的话答案就是,非素数我们可以按唯一分解定理将其分成
具体见代码。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
using namespace std;
typedef long long ll;
void err(){cout << "\033[39;0m" << endl;}
template<template<typename...> class T, typename t, typename... A>
void err(T<t> a, A... x){for (auto v: a) cout << v << ' '; err(x...);}
template<typename T, typename... A>
void err(T a, A... x){cout << a << ' '; err(x...);}
const int N = 1e6 + 100;
ll prime[N];
int tot;
bool vis[N];
void pre()
{
tot = 0;
for (int i = 2; i <= 1000010; i++)
{
if (!vis[i])
prime[++tot] = i;
for (int j = 1; j <= tot && i * prime[j] <= 1000010; j++)
{
vis[i * prime[j]] = 1;
if (i % prime[j] == 0)
break;
}
}
}
ll cnt[N];
ll val[N];
const ll mod = 998244353;
int main()
{
int T;
scanf("%d", &T);
pre();
while (T--)
{
ll l, r, k;
scanf("%lld%lld%lld", &l, &r, &k);
for (int i = 0; i <= r - l; i++)
{
cnt[i] = 1;
val[i] = i + l;
}
for (int i = 1; i <= tot && prime[i] * prime[i] <= r; i++)
{
//dbg(i);
ll cur = l / prime[i] * prime[i];
while (cur < l)
{
cur = cur + prime[i];
}
for (; cur <= r; cur += prime[i])
{
ll c = 0;
while (val[cur - l] % prime[i] == 0)
{
val[cur - l] /= prime[i];
c++;
}
cnt[cur - l] = (cnt[cur - l] * (c * k % mod + 1)) % mod;
//dbg(cur, cnt[cur - l + 1]);
}
}
ll ans = 0;
for (int i = 0; i + l <= r; i++)
{
if (val[i] == 1)
ans = (ans + cnt[i]) % mod;
else
ans = (ans + cnt[i] * (k + 1) % mod) % mod;
}
printf("%lld\n", ans);
}
return 0;
}