Problem Description
In mathematics, the function
d(n)
denotes the number of divisors of positive integer
n
.
For example, d(12)=6 because 1,2,3,4,6,12 are all 12 's divisors.
In this problem, given l,r and k , your task is to calculate the following thing :
For example, d(12)=6 because 1,2,3,4,6,12 are all 12 's divisors.
In this problem, given l,r and k , your task is to calculate the following thing :
(∑i=lrd(ik))mod998244353
Input
The first line of the input contains an integer
T(1≤T≤15)
, denoting the number of test cases.
In each test case, there are 3 integers l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107) .
In each test case, there are 3 integers l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107) .
Output
For each test case, print a single line containing an integer, denoting the answer.
Sample Input
3 1 5 1 1 10 2 1 100 3
Sample Output
10 48 2302题意: 对l~r中的每个数的因子个数求和(最后求余);思路: 对于每一个数而言可以进行分解质因数 num=p1^k1*p2^k2……pn^kn 的形式,而当前这个数的因子和(可以整除这个数的数)就是(k1+1)*(k2+1)……*(kn+1)个。而现在题中求i^k,分解质因子中将k乘入可得(k1*k+1)*(k2*k+1)……(kn*k+1)个。即现在要求每个数的分解质因数,显然遍历l~r会超时,于是我们想到对于用素数去遍历,对于任意一个数num<10^12 它的质因数只全部小于<num/2(还是超内存) 于是我们想到对于一个num他的质因数只有可能有一个大于根号num(这样内存就不会爆了,可以线性打表出1e6以内的素数)。对每个素数去遍历l~r,记录下来,得到因式分解,对于l~r的质数加k+1,合数就按照上面的公式计算出来,全部求和得到结果。#include<stdio.h> #include<string.h> #include<math.h> using namespace std; typedef long long LL; const LL MOD=998244353; const LL MAXN=1e6+1; int primer[MAXN],cnt; LL p[MAXN]; LL f[MAXN],num[MAXN]; LL l,r,k; void isprimer() //筛选素数存于p数组 { memset(primer,0,sizeof(primer)); cnt=0; primer[1]=1; for(LL i=2;i<MAXN;i++) if(!primer[i]) { p[cnt++]=i; for(LL j=i*i;j<MAXN;j+=i) primer[j]=1; } } int main() { isprimer(); int T; scanf("%d",&T); while(T--) { scanf("%lld%lld%lld",&l,&r,&k); LL ans=0; if(l==1) ans=1,l=2; LL t=r-l; for(LL i=0;i<=t;i++) f[i]=l+i,num[i]=1; // for(int s=0;s<=t;s++) printf(" %lld ",f[s]); // printf("\n"); for(LL i=0;i<cnt&&p[i]*p[i]<=r;i++) { LL temp=l; if(temp%p[i]) temp=(temp/p[i]+1)*p[i]; //printf(" %lld %lld\n",temp,p[i]); for(LL j=temp;j<=r;j+=p[i]) { LL tim=0; while(f[j-l]%p[i]==0) { tim++; f[j-l]/=p[i]; } num[j-l]=(num[j-l]*(tim*k+1))%MOD; } } // for(int s=0;s<=t;s++) printf(" %lld ",f[s]); // printf("\n"); for(LL i=0;i<=t;i++) if(f[i]==1) ans=(ans+num[i])%MOD; else ans=(ans+(k+1)*num[i])%MOD; printf("%lld\n",ans); } return 0; }