2017 Multi-University Training Contest - Team 4 hdu6069 Counting Divisors
2017-08-04 01:33
435 查看
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=6069
题目:
Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 1235 Accepted Submission(s): 433
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
Source 2017 Multi-University Training Contest - Team 4
思路:
首先需要知道:一个数可以用唯一分解定理表示成:n=p1^a1*p2^2......*pn^an
质约数个数为(a1+1)*(a2+1)*....*(an+1)
那么n^k的质约数个数为(a1*k+1)*(a2*k+1)*.....*(an*k+1)
所以这题的关键是求l,r区间每个数的质约数有那些,且次数是多少。
考虑到:l,r最大为1e12,所以枚举1-1e6内的所有素数后即可知道l,r中每个数的质约数有哪些,同时可以知道次数是多少
但是直接在1-1e6的素数表内查找l,r中的某个数的素约数的时间复杂度是O(1e6),显然不可行。
所以可以通过线性筛的思想来求:对于1-1e6的素数,考虑他会在l,r内筛掉哪些数即可。
因为1e12每个数最多有20左右的质约数,所以时间复杂度是O((r-l)*20)+O(1e5)(质数表大小)
#include <bits/stdc++.h> using namespace std; #define MP make_pair #define PB push_back typedef long long LL; typedef pair<int,int> PII; const double eps=1e-8; const double pi=acos(-1.0); const int K=1e6+7; const int mod=998244353; LL ql,qr,qk,cnt,ls[K],sum[K],pr[K]; bool pa[K]; void init(void) { for(int i=2;i<=1000000;i++) if(!pa[i]) { pr[cnt++]=i; for(int j=i*2;j<=1000000;j+=i) pa[j]=1; } } LL sc(int t) { LL ans=0; for(LL i=ql;i<=qr;i++) sum[i-ql]=1,ls[i-ql]=i; for(int i=0;i<cnt;i++) { for(LL j=max(2LL,(ql+pr[i]-1)/pr[i])*pr[i];j<=qr;j+=pr[i]) { LL cnt=0; while(ls[j-ql]%pr[i]==0) ls[j-ql]/=pr[i],cnt++; sum[j-ql]=(sum[j-ql]*(qk*cnt+1))%mod; } } for(LL i=ql;i<=qr;i++) { if(ls[i-ql]!=1) sum[i-ql]=(sum[i-ql]*(qk+1))%mod; ans+=sum[i-ql]; if(ans>=mod) ans-=mod; } return ans; } int main(void) { //freopen("in.acm","r",stdin); int t;scanf("%d",&t); init(); while(t--) { scanf("%lld%lld%lld",&ql,&qr,&qk); printf("%lld\n",sc(t)); } return 0; }
相关文章推荐
- HDU-6069 Counting Divisors - 2017 Multi-University Training Contest - Team 4(分解质因子区间筛法)
- 2017 Multi-University Training Contest - Team 4 :Counting Divisors(数论:素数筛选+分解质因子+求因子数)
- 2017 Multi-University Training Contest - Team 4:1003. Counting Divisors(积性函数)
- 2017 Multi-University Training Contest 4 && HDOJ 6069 Counting Divisors 【区间筛法】
- HDU6069 2017 Multi-University Training Contest - Team 4 1003 Counting Divisors(唯一分解定理+思维优化)
- 2017 Multi-University Training Contest - Team 4-hdu6069 Counting Divisors
- 2017 Multi-University Training Contest - Team 4 :1003&hdu6069、Counting Divisors
- 2017 Multi-University Training Contest - Team 6:1008&hdu6103、Kirinriki
- 2017 Multi-University Training Contest - Team 6 Inversion(排序)
- 2017 Multi-University Training Contest - Team 6 的签到题
- 2017 Multi-University Training Contest - Team 7:1005. Euler theorem(答案是(n+3)/2)
- 2017 Multi-University Training Contest - Team 7:1002. Build a tree(递归)
- 2017 Multi-University Training Contest - Team 7:1003. Color the chessboard(...)
- 2017 Multi-University Training Contest - Team 7
- HDU 6172 Array Challenge(打表+矩阵快速幂)——2017 Multi-University Training Contest - Team 10
- 2017 Multi-University Training Contest - Team 1 1006 Function(置换群)
- hdoj 6060(2017 Multi-University Training Contest - Team 3) RXD and dividing
- HDU6043 & 2017 Multi-University Training Contest - Team 1
- hdu 6034 Balala Power!(贪心)( 2017 Multi-University Training Contest - Team 1 )(无耻之sort)
- 2017 Multi-University Training Contest - Team 1 1002&&HDU 6034 Balala Power!【字符串,贪心+排序】