Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
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
Source
官方题解:
唯一分解定理
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<cstdio> #include<cmath> #include<string> #include<queue> #include<algorithm> #include<stack> #include<cstring> #include<vector> #include<list> #include<set> #include<map> #include<stdlib.h> #include<time.h> #include<bits/stdc++.h> using namespace std; #define LL long long #define pi (4*atan(1.0)) #define bug(x) cout<<"bug"<<x<<endl; const int N=1e5+10,M=1e6+10,inf=2147483647; const LL INF=1e18+10,mod=998244353; const int MAXN=1000001; int prime[MAXN];//保存素数 bool vis[MAXN];//初始化 int Prime(int n) { int cnt=0; memset(vis,0,sizeof(vis)); for(int i=2; i<n; i++) { if(!vis[i]) prime[cnt++]=i; for(int j=0; j<cnt&&i*prime[j]<n; j++) { vis[i*prime[j]]=1; if(i%prime[j]==0) break; } } return cnt; } LL num[M],ans[M]; int main() { int cnt=Prime(1000000); int T; scanf("%d",&T); while(T--) { for(int i=0; i<1000005; i++) num[i]=1,ans[i]=1; LL l,r,K; scanf("%lld%lld%lld",&l,&r,&K); for(int q=0; q<cnt; q++) { int i=prime[q]; LL L=(l%i==0?l:(l/i+1)*i); for(LL j=L; j<=r; j+=i) { LL temp=j,base=1; int x=0; while(temp%i==0) { x++; temp/=i; base*=i; } ans[j-l+1]*=(1LL*K*x+1)%mod; ans[j-l+1]%=mod; num[j-l+1]*=base; } } for(LL i=l; i<=r; i++) { if(num[i-l+1]!=i) ans[i-l+1]*=K+1,ans[i-l+1]%=mod; } LL out=0; for(LL i=l;i<=r;i++) out+=ans[i-l+1],out%=mod; printf("%lld ",out); } return 0; }