Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 658 Accepted Submission(s): 219
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
Recommend
idea:设n=p1c1p2c2...pmcm,则d(nk)=(kc1+1)(kc2+1)...(kcm+1)。
比赛时被因子和这个玩意卡哭了。一个数必定是要在根号n的复杂度内求出他的因子,但是如果这个数是素数。那么一定会消耗根号n的时间去处理。
所以如果我们能先不处理素数,先处理其他数,(因为素数的结果最后肯定是k+1),所以我们如果能把合数先处理完那么就能在很快的时间内得出答案。然而一个1e12的数,开根是1e6。那么他的因子是素数筛的素数,如果素数筛里找不到他的因子,那么这个数肯定是素数。然后对于一个区间,
如果p为倍数,如果要能被p整除,肯定得在这个区间上跳p个位置。具体看代码:
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <algorithm>
using namespace std;
#define pi acos(-1)
#define endl '\n'
#define srand() srand(time(0));
#define me(x,y) memset(x,y,sizeof(x));
#define foreach(it,a) for(__typeof((a).begin()) it=(a).begin();it!=(a).end();it++)
#define close() ios::sync_with_stdio(0); cin.tie(0);
#define FOR(x,n,i) for(int i=x;i<=n;i++)
#define FOr(x,n,i) for(int i=x;i<n;i++)
#define W while
#define sgn(x) ((x) < 0 ? -1 : (x) > 0)
#define bug printf("***********\n");
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL LINF=0x3f3f3f3f3f3f3f3fLL;
const int dx[]={-1,0,1,0,1,-1,-1,1};
const int dy[]={0,1,0,-1,-1,1,-1,1};
const int maxn=1000;
const int maxx=1e7+100;
const double EPS=1e-7;
const int mod=998244353;
template<class T>inline T min(T a,T b,T c) { return min(min(a,b),c);}
template<class T>inline T max(T a,T b,T c) { return max(max(a,b),c);}
template<class T>inline T min(T a,T b,T c,T d) { return min(min(a,b),min(c,d));}
template<class T>inline T max(T a,T b,T c,T d) { return max(max(a,b),max(c,d));}
inline int Scan()
{
int Res=0,ch,Flag=0;
if((ch=getchar())=='-')Flag=1;
else if(ch>='0' && ch<='9')Res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')Res=Res*10+ch-'0';
return Flag ? -Res : Res;
}
//freopen( "in.txt" , "r" , stdin );
//freopen( "data.out" , "w" , stdout );
//cerr << "run time is " << clock() << endl;
int val,vis[maxx];
LL l,r,f[maxx],d[maxx],pri[maxx];
int k;
void init()
{
for(int i=2;i<maxx;i++)
{
if(!vis[i])pri[val++]=i;
for(int j=0;j<val&&i*pri[j]<maxx;j++)
{
vis[i*pri[j]]=1;
if(i%pri[j]==0)break;
}
}
}
void work(LL p)
{
for(LL i=l/p*p;i<=r;i+=p)
{
if(i>=l)
{
LL cnt=0;
while(f[i-l]%p==0)
f[i-l]/=p,cnt++;
d[i-l]=1LL*d[i-l]*(cnt*k+1ll)%mod;
}
}
}
void solve()
{
cin>>l>>r;
k=Scan();
for(LL i=l;i<=r;i++)
{
f[i-l]=i;
d[i-l]=1;
}
for(LL i=0;i<val;i++)
{
if(pri[i]*pri[i]>r) break;
work(pri[i]);
}
LL ans=0;
for(LL i=0;i<=(r-l);i++)
{
if(f[i]>1)
{
d[i]=1ll*d[i]*(LL)(k+1);
d[i]%=mod;
}
ans=(ans+d[i])%mod;
}
cout<<ans<<endl;
}
int main()
{
//freopen( "in.txt" , "r" , stdin );
// freopen( "out.txt" , "w" , stdout );
init();
int t;
t=Scan();
while(t--)
solve();
}
我还是太菜了。