HDU 6069 Counting Divisors
原题连接:
http://acm.hdu.edu.cn/showproblem.php?pid=6069
应该是比较简单的。(开始一直怀疑自己读错题了)
除数函数是积性的。
τ0(n)=∑i|ni0
τ0(n)=∏i=1r(ai+1)
其中
n
的质因数分解形式为:
n=∏i=1rPaii
明显:
nk=(∏i=1rPaii)k=∏i=1rPai∗ki
τ0(nk)=∏i=1r(kai+1)
对区间 [l,r] 质因数分解即可。
#include <iostream>
#define MAXN 1001106
using namespace std;
typedef long long LL;
const LL mod=998244353;
LL A[MAXN+100];
LL B[MAXN+100];
LL Prim[MAXN*2];
bool vis[MAXN*2];
LL deep;
void prim()
{
for(int i=2,s=MAXN*2;i<s;i++)
{
if(vis[i])continue;
Prim[deep++]=(LL)i;
if(i>MAXN)break;
for(int j=i+i;j<s;j+=i) vis[j]=true;
}
}
int main ()
{
prim();
int T;
scanf("%d",&T);
while(T--)
{
LL l,r,K;
cin>>l>>r>>K;
int si=(int)(r-l)+1;
for(int i=0;i<si;i++)
{
B[i]=l+(LL)i;
A[i]=1;
}
LL ans=0;
for(LL i=0;i<deep;i++)
{
LL k=Prim[i];
for(LL di=(k-l%k)%k; di<si ; di+=k)
{
LL a=0;
while(B[di]%k==0)
{
B[di]/=k;
a++;
}
A[di]=A[di]*(K*a+1);
if(A[di]>mod)A[di]%=mod;
}
}
for(LL i=0;i<si;i++)
{
if(B[i]>1)A[i]=A[i]*(K+1)%mod;
ans+=A[i];
if(ans>=mod)ans-=mod;
}
cout<<ans%mod<<endl;
}
return 0;
}