原题:HDU - 6069
题意:令d(x)表示x的因子数,求 ,r,l 为1e12 ,r-l为1e6
解析:
刚开始想到的是欧拉函数值,结果 就劝退了,换一种常规的思路,从因子的角度去思考,按照基本定理:
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define ll long long
LL read(){ LL ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
const LL mod=998244353ll;
const int N=1000000;
LL pri[N+9],now;
bool vis[N+9];
void init(){
now=0;vis[1]=1;
for(int i=2;i<=N;i++){
if(!vis[i])pri[++now]=i;
for(int j=1;j<=now&&pri[j]*i<=N;j++){
vis[pri[j]*i]=1;
if(i%pri[j]==0)break;
}
}
}
LL ans[N+9],Num[N+9];
LL l,r,k;
int id(LL x){return x-l+1; }//l~r拉到1~r-l+1以开数组
LL val(int x){return x+l-1;}
int main(){
init();
int t=read();
while(t--){
l=read(),r=read(),k=read();
for(int i=1,idx=id(r);i<=idx;i++)ans[i]=1,Num[i]=val(i);
for(int i=1;i<=now;i++){//枚举素数
LL J=pri[i];
LL st=(l/J*J==l)?l:(l/J*J+J);//第一个区间内此素数的倍数
for(int idx=id(st),en=id(r) ; idx<=en ; idx+=J){//枚举区间内的数
int ct=0;
while(Num[idx]%J==0)Num[idx]/=J,ct++;
ans[idx]=ans[idx]*((k*ct+1)%mod)%mod;
}
}
LL A=0;
for(int i=1,en=id(r);i<=en;i++)
if(Num[i]>1)A=(A+((k+1)*ans[i]%mod))%mod;
else A=(A+ans[i])%mod;
printf("%lld\n",A);
}
}