Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 3798 Accepted Submission(s): 1385
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
In this problem, given l,r
(∑
i=l
r
d(i
k
))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≤10
12
,r−l≤10
6
,1≤k≤10
7
)
.
In each test case, there are 3
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
Source
Recommend
liuyiding | We have carefully selected several similar problems for you: 6275 6274 6273 6272 6271
思路:先预处理找出小于1e6的素数,然后枚举这些素数,用一个数组num存储[l,r]之间的数,找出[l,r]区间内能顾整除这些素数的数(只需要找出区间中第一个能整除某个素数的数,接下来不断递增这个素数的大小,就能找出所有区间内能够整除这个素数的数了),并不断更新num数组,最终将区间内的数都通过唯一分解定理分解。留意num数组中那些不为1的元素,不为1意味着剩余了一个大素数,需要再乘(1+k)
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int mod=998244353;
const int maxn=1e6+5;
int prime[maxn],vis[maxn],tot;
long long l,r,k,num[maxn],a[maxn];
void init()
{
tot=0;
memset(vis,0,sizeof(vis));
for(int i=2;i<maxn;i++)
{
if(!vis[i])
{
vis[i]=1;
prime[tot++]=i;
// printf("%d\n",i);
for(int j=2;j*i<maxn;j++)
vis[j*i]=1;
}
}
}
int main()
{
init();
int t,i;
long long sum;
// printf("111");
scanf("%d",&t);
while(t--)
{
scanf("%lld %lld %lld",&l,&r,&k);
//将[l,r]中的数赋值给num数组,数组a存储其因数个数
for(i=0;i<=r-l;i++)
{
num[i]=i+l;
a[i]=1;
}
for(i=0;i<tot;i++)
{
long long temp=((l/prime[i])+(l%prime[i]?1:0))*prime[i];//找出[l,r]中第一个能整除此素数的数
for(long long j=temp;j<=r;j+=prime[i])
{
int cnt=0;
while(num[j-l]%prime[i]==0)
{
cnt++;
num[j-l]/=prime[i];
}
a[j-l]=(a[j-l]*((1+k*cnt)%mod))%mod;//别忘了取模
}
}
sum=0;
//遍历num数组,不为1的话意味着还剩一个大素数,需要再处理
for(i=0;i<=r-l;i++)
{
if(num[i]!=1)
a[i]=(a[i]*(1+k))%mod;
sum=(sum+a[i])%mod;
}
printf("%lld\n",sum);
}
return 0;
}