hdu 6069 统计区间约数的个数 2017 Multi-University Training Contest
来源:互联网 发布:union all 不同数据库 编辑:程序博客网 时间:2024/06/14 06:48
Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 1720 Accepted Submission(s): 629
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, givenl,r and k , your task is to calculate the following thing :
(∑i=lrd(ik))mod998244353
For example,
In this problem, given
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 are3 integers l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107) .
In each test case, there are
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
首先我们要知道一个定理
一个数的约数的个数等于,唯一分解成质数的形式后,每一个指数加一后累乘的结果
本题就比较简单了,比赛的时候傻逼了
枚举10的六次方以内的质数,不超过八万好像,忘了,可以运行程序看看就知道了,反正不多
然后再区间内部,枚举质数的倍数,这样可以减少很多运算量,然后计算这个质数在这个倍数里面可以分解得到多少个,即上面说的指数
需要注意的是,分解后可能会有大于10的六次方的指数,最后把这些数另外处理一下即可
#include<math.h>#include<stdio.h>#include<algorithm>using namespace std;#define LL long long#define mod 998244353#define MAXN 1000006LL sum[MAXN],num[MAXN];LL primer[MAXN];LL flag[MAXN];int cnt=0;void get_primer(){ flag[0]=flag[1]=1; LL sqrtmaxn=(LL)sqrt((double)MAXN); for(int i=2;i<MAXN;i++){ if(primer[i]==0){ flag[i]=flag[i-1]; primer[cnt++]=i; if(i<sqrtmaxn) for(int j=i*i;j<MAXN;j+=i) primer[j]=1; } else flag[i]=(flag[i-1]*i)%mod; }}int main(){ int T; get_primer(); LL a,b,c,ans; //freopen("in.txt","r",stdin); scanf("%d",&T); while(T--) { scanf("%lld%lld%lld",&a,&b,&c); for(int i=0;i<=b-a+1;i++) sum[i]=1,num[i]=a+i; LL pos,t,temp; for(int i=0;i<cnt;i++){ if(primer[i]>(b/2+1)) break; t=a/primer[i]; if(a%primer[i]) t++; pos=t*primer[i]; for(LL j=pos;j<=b;j+=primer[i]){ t=0; while(num[j-a]%primer[i]==0) num[j-a]/=primer[i],t++; sum[j-a]=sum[j-a]*(c*t+1)%mod; } } ans=0; for(LL j=a;j<=b;j++){ if(num[j-a]>1) sum[j-a]=sum[j-a]*(c+1)%mod; ans=(ans+sum[j-a])%mod; } printf("%lld\n",ans); } return 0;}
阅读全文
0 0
- hdu 6069 统计区间约数的个数 2017 Multi-University Training Contest
- hdu 6069 Counting Divisors(约数个数)(2017 Multi-University Training Contest
- HDU 3068 2017 Multi-University Training Contest
- HDU 6034 & 2017 Multi-University Training Contest
- hdu 6034 2017 Multi-University Training Contest
- HDU 3065 2017 Multi-University Training Contest
- HDU 6047 2017 Multi-University Training Contest
- HDU 6052 2017 Multi-University Training Contest
- HDU 6058 2017 Multi-University Training Contest
- HDU 6078 2017 Multi-University Training Contest
- hdu 6058 Kanade's sum [区间第k大数求和] [2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 2017 Multi-University Training Contest
- 【数论-莫比乌斯】bzoj 2301 莫比乌斯+容斥
- Trie(字典树)的Java实现
- Cocoapods安装中出现的问题解决
- Oracle总结
- 客户端和服务器编码问题
- hdu 6069 统计区间约数的个数 2017 Multi-University Training Contest
- javaweb Filter的使用方法以及配置xml文件
- Android的LocalSocket实现及SELinux权限设置.编译(应用层和native通信)
- JQ AJAX 调用后台方法--
- php面向对象__toString() 用法详解
- php 打印空心金字塔
- 百度地图之判断标注点是不是在所画的圆形中
- Android应用的启动时间
- 如何免 sudo 使用 docker