URL : http://acm.hdu.edu.cn/showproblem.php?pid=6069
求:
(∑i=lrd(ik))mod998244353
l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107)
题解:
设
n=pc11pc22...pcmmn=p
,则
d(nk)=(kc1+1)(kc2+1)...(kcm+1)
枚举不超过
r√
的所有质数
p
,再枚举区间
时间复杂度
O(r√+(r−l+1)loglog(r−l+1))
#include<stdio.h>
#define it (pos - l)
typedef long long LL;
const int MOD = 998244353;
const int MAXN = 1e6 + 500;
const int o = 1000000;
int p[MAXN], prm[MAXN], sz;
LL arr[o + 10], d[o + 10];
void init() {
for(int i = 2; i < MAXN; ++i) {
if(!p[i]) prm[sz++] = i;
for(int j = 0; j < sz; ++j) {
int t = i * prm[j];
if(t >= MAXN) break;
p[t] = true;
if(i%prm[j] == 0) break;
}
}
}
LL work(LL l, LL r, LL k) {
for(int i = 0; i < sz; ++i) {
LL pos = (l + prm[i] - 1) / prm[i] * prm[i];
while(pos <= r) {
LL cnt = 0;
while(arr[it] % prm[i] == 0) {
++cnt;
arr[it] /= prm[i];
}
d[it] *= cnt * k + 1;
d[it] %= MOD;
pos += prm[i];
}
}
LL res = 0;
for(LL pos = l; pos <= r; ++pos) {
// printf("#%lld\n", d[it]);
if(arr[it] == 1) {
res += d[it];
} else {
res += d[it] * (k +1);
}
res %= MOD;
}
return res;
}
int main()
{
init();
int T;
LL l, r, k;
scanf("%d", &T);
while(T--) {
scanf("%lld%lld%lld", &l, &r, &k);
for(LL pos = l; pos <= r; ++pos) {
d[it] = 1;
arr[it] = pos;
}
LL ans = work(l, r, k);
printf("%lld\n", ans);
}
return 0;
}