(hdu6069)2017杭电多校联赛第四场-Counting Divisors 因子个数求和(数论)

来源:互联网 发布:js 设置div class 编辑:程序博客网 时间:2024/06/08 16:12

Counting Divisors

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1322    Accepted Submission(s): 470


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 :

(i=lrd(ik))mod998244353

 

Input
The first line of the input contains an integer T(1T15), denoting the number of test cases.

In each test case, there are 3 integers l,r,k(1lr1012,rl106,1k107).
 

Output
For each test case, print a single line containing an integer, denoting the answer.
 

Sample Input
31 5 11 10 21 100 3
 

Sample Output
10482302
 

Source
2017 Multi-University Training Contest - Team 4


题目大意:给你一个l, r, k, 计算这个式子的值。

解题思路:由数论知识我们可以知道每一个数n都可以表示成素数的乘积,根据约数个数定理:n=p1^a1×p2^a2×p3^a3*…*pk^ak,n的约数的个数就是(a1+1)(a2+1)(a3+1)…(ak+1).所以我们先预处理素数,然后找可以在(L,R)之间的数的素数因子,得到每一个数关于这个素数的倍数,就可以得到所有数的所有因子个数。然后加上所有 数的因子个数就可以了,因为r-l 的范围是10^6,所以是不会超时的。

标程代码:
//标程,不喜勿喷 #include<cstdio>typedef long long ll;const int N=1000010,P=998244353;int Case,i,j,k,p[N/10],tot,g[N],ans;ll n,l,r,f[N];bool v[N];inline void work(ll p){//计算每一个素数的倍数的值计入因子个数内   for(ll i=l/p*p;i<=r;i+=p)      if(i>=l){    int o=0;    while(f[i-l]%p==0)f[i-l]/=p,o++;//o表示素数的倍数     g[i-l]=1LL*g[i-l]*(o*k+1)%P;//计算进因子个数内   }}int main(){//数据规模10^12,所以素数范围只需要开根号即10^6即可   for(i=2;i<N;i++)//素数筛选   {    if(!v[i])p[tot++]=i;    for(j=0;j<tot&&i*p[j]<N;j++){//将素数存入p数组内       v[i*p[j]]=1;      if(i%p[j]==0)break;    }  }  scanf("%d",&Case);  while(Case--){    scanf("%lld%lld%d",&l,&r,&k);    n=r-l;    for(i=0;i<=n;i++)f[i]=i+l,g[i]=1;    for(i=0;i<tot;i++){//计算在范围内可以出现的素数       if(1LL*p[i]*p[i]>r)break;      work(p[i]);//将可以出现的素数代入范围计算,计算区间内每一个 数的个数值     }    for(ans=i=0;i<=n;i++){      if(f[i]>1)g[i]=1LL*g[i]*(k+1)%P;      ans=(ans+g[i])%P;    }    printf("%d\n",ans);  }  return 0;}

题目链接:点击打开链接