题意:求d(i)的累加和,d是i的因子数。
思路:
枚举不超过sqrt(r)的所有素数p,去删p的倍数。
用b[i] = 0,表示是素数。质数的倍数置1,然后分解这个数,用c[i]表示这个数被除完前面的素数后的商。
用tt[i]表示这个数的累乘。最后c[i] > 1的话代表,这个数还有一个很大的素数,tt[i]再累乘下。
#include<bits/stdc++.h>
using namespace std;
const int MAX_N = 1e6+5;
const long long MOD = 998244353;
int all=0,b[MAX_N];
long long tt[MAX_N],c[MAX_N];
long long ans,k;
long long pr[MAX_N/10+100];
bool isp[MAX_N+10];
void init()
{
all = 0;
memset(isp,0,sizeof(isp));
for(int i=2;i<=MAX_N;i++)
{
if(!isp[i]){
pr[all++] = i;
}for(int j=0;j<all;j++){
long long t = 1LL*pr[j]*i ;
if(t<=MAX_N){
isp[t] = true;
if(i%pr[j]==0)break;
}else{
break;
}
}
}
return;
}
int main()
{
int n;
long long l,r;
init();
cin>>n;
while(n--)
{
scanf("%lld%lld%lld",&l,&r,&k);
ans = 0ll;
k %= MOD;
memset(b,0,sizeof b);
memset(tt,0,sizeof tt);
memset(c,0,sizeof c);
for(int i = 0; i < all; i++)
{
if(pr[i] * pr[i] > r)
break;
long long tp = pr[i];
long long zh = l / tp;
if(l % tp != 0)
zh++;
if(zh == 1ll)
zh++;
for(long long j = zh * tp; j <= r; j += tp)
{
b[j-l] = 1;
long long num = 0;
if(c[j-l] == 0ll)
c[j-l] = j;
while ( c[j-l] % tp == 0 )
{
c[j-l] /= tp;
num++;
}
if(tt[j-l] == 0ll)
tt[j-l] = 1ll;
tt[j-l] = tt[j-l] * ((k*num+1) % MOD) % MOD;
}
}
for(long long i = l; i <= r; i++)
{
if(i == 1)
ans = (ans + 1) % MOD;
else if(!b[i-l])
ans = (ans + (k + 1) )% MOD;
else
{
if(c[i-l] > 1) tt[i-l] = (tt[i-l]*(k+1)) % MOD;
ans = (ans + tt[i-l] ) % MOD;
}
}
printf("%lld\n",ans);
}
return 0;
}