题目链接

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(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).

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

分析:

如果一个数n可以分解成n=p1m1*p2m2*···*pn^mn的话(其中p1,p1···为素数),那么这个数的因子个数就为(m1+1)*(m2+1)*···*(mn+1)。

同样的,这个数由n变为nk的话,相应的次数前面分别乘以k即可。即nk的因子个数为(k*m1+1)*(km2+1)*···*(kmn+1)。

这个问题解决掉之后,我们会发现数据范围太大,我们的数组分本没办法开到那么大,我们可以把数据由前半部分来推出后半部分。

先打个1e6范围内的素数表,然后枚举可行范围内的每个素数,在区间[ l , r ]内寻找所有的该素数的倍数,将其分解质因数。

到最后如果一个数没有变成1,那就说明这个数是大于1e6的质数。(质数只有1和它本身)那么如果按照规律计算的话,只需要乘上一个(k+1)就行了。

#include<iostream>
#include<stdio.h>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=1e6+5;
const int mod=998244353; int n;
int cnt=0;
int primes[maxn];
int vis[maxn]; void get_primes()///筛选法求出1e6之内的素数,比1e6大的素数可以通过这些素数间接的求出来
{
int m=sqrt(maxn+0.5);///开方,循环到这个就行了
for(int i=2; i<=m; i++)
{
if(!vis[i])
{
for(int j=i*i; j<=maxn; j+=i)
vis[j]=1;
}
}
for(int i=2; i<=maxn; i++)
if(!vis[i]) primes[cnt++]=i;
} ll l, r, k;
ll sum[maxn], num[maxn]; int main()
{
get_primes();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld",&l,&r,&k);
ll ans=0;
///因为l和r的范围比较大,但是它们之间的差值不会查过1e6,可以将数组缩小一点
for(ll i=l; i<=r; i++)
{
sum[i-l]=1;///个数
num[i-l]=i;///表示的是这个数
} for(int i=0; i<cnt && primes[i]*primes[i]<=r; i++)///所有的素数
{
///求出的是[l,r]区间中第一个能够被rimes[i]整除的数
ll tmp=ceil((long double)l/primes[i])*primes[i];
for(ll j=tmp; j<=r; j+=primes[i])///枚举所有的这个素数的倍数
{
if(num[j-l]%primes[i]==0)
{
int res=0;
while(num[j-l]%primes[i]==0)
{
res++;
num[j-l]/=primes[i];
}
sum[j-l]=(sum[j-l]*(((ll)res*k+1))%mod)%mod;
}
}
} for(ll i=l; i<=r; i++)
{
if(num[i-l]!=1)///那些本身是素数的数
sum[i-l]=(sum[i-l]*(k+1))%mod; ///大于1e6的质数
ans=(ans+sum[i-l])%mod; }
printf("%lld\n",ans);
}
return 0;
}

最新文章

  1. log4cplus 在配置文件中设置文件路径,程序自动创建目录,且在日志文件前按日期创建相应的目录
  2. 经典排序算法---冒泡排序(Bubble Sort)
  3. SQL日语词汇
  4. iOS开发-布局基础
  5. hadoop2.2编程: SequenceFileWritDemo
  6. 10.30 afternoon
  7. bbc 大数据
  8. 【HDOJ】2822 Dogs
  9. 使用纯css代码实现div的“回”字型“叠放”效果
  10. ZOJ 3702 Gibonacci number
  11. CentOS6.5编译安装Redis
  12. 结队编程study
  13. Linux Shell 编程语法
  14. Dynamics 365 CE中使用FetchXML进行聚合运算
  15. 20165223《网络对抗技术》Exp5 MSF基础应用
  16. 你好!酷痞 Coolpy
  17. OpenGL创建一个三角形,并且颜色渐变(绿—&gt;黑—&gt;绿)
  18. windows旋转屏幕快捷键配置
  19. [转]Mariadb的root密码忘记后的解决方法
  20. hdu 1595 find the longest of the shortest(dijstra + 枚举)

热门文章

  1. JavaScript设计模式学习之路——继承
  2. SSH管理(重启 停止 运行 安装)centos7
  3. HDU4669_Mutiples on a circle
  4. ZOJ1827_The Game of 31
  5. 迭代器 每迭代一次 指针往下面移动一次 除非JVM回收了内存 否则 他的指针不会回到原地
  6. HDU5266-pog loves szh III
  7. noip模拟题《序》sort
  8. 【bzoj2829】信用卡凸包 凸包
  9. web项目访问路径上为什么不能写上WebContent
  10. &#128314; Garbage Remembering Exam UVA - 11637()