【数论】hdu 6069 Counting Divisors
2017-08-07 10:11
483 查看
Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 2815 Accepted Submission(s): 1040
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 :
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
题意:d(i):i 的因子个数,给定范围内任意l,r,k 计算如上公式值;
思路:d(i),把 i 分解为质因子的形式,然后各个质因子的幂+1,然后相乘,就是 i 的因子个数;
开一个数组来保存1~1e6的质数,1e6范围内的质数就够用了;
之前的代码是把 l , r 的循环放在外部,质数的循环放在内部,用来求每一个数的不同质因子的个数,这样的复杂度是n*tot(质数的个数);
把质数的循环放在外部的话,可以优化:
代码:
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #define ll long long #define mod 998244353 const int N=1000006; int is_prime[N+10],prime[N+10]; int tot=0; ll ans; ll l,r,k; void get_prime() { int i,j; tot=0; memset(is_prime,false,sizeof(is_prime)); for(i=2; i<N; i++) { if(!is_prime[i]) prime[tot++]=i; for(j=0; (j<tot)&&(i*prime[j]<N); j++) { is_prime[i*prime[j]]=true; if(i%prime[j]==0) break; } } } ll f ,g ; void work() { for(ll i=l; i<=r; i++) f[i-l]=i,g[i-l]=1; for(int i=0; i<tot; i++) { if(prime[i]*prime[i]>r) // 优化 ,如果这个素数的平方都大于r,那么l~r没有能够整除这个素数和这个素数之后的所有素数了; break; for(ll j=l/prime[i]*prime[i]; j<=r; j+=prime[i]) //优化 ,每一次都是j+=prime[i]; { if(j>=l) { int cnt=0; while(f[j-l]%prime[i]==0) { cnt++; f[j-l]/=prime[i]; } g[j-l]=g[j-l]*(cnt*k+1)%mod; } } } for(ll i=l; i<=r; i++) { if(f[i-l]>1) g[i-l]=g[i-l]*(k+1)%mod; ans=ans+g[i-l]; if(ans>=mod) ans%=mod; } } int main() { int T; scanf("%d",&T); get_prime(); while(T--) { ans=0; scanf("%I64d%I64d%I64d",&l,&r,&k); work(); printf("%I64d\n",ans%mod); } return 0; }
代码中有 l / prime[i] * prime[i] ,这个代码是找到离 l 最近的,小于等与 l 的,能够整除 prime[i] 的数;
参考队友的思路,代码,≧ ﹏ ≦
相关文章推荐
- HDU 6069 Counting Divisors 【数论】
- 【hdu 6069】 Counting Divisors 【思维+数论】
- HDU_6069 Counting Divisors 【数论】
- HDU 6069 Counting Divisors(数论)
- HDU 6069 数论 区间素数筛(+赛后反思
- hdu 4990 Reading comprehension(数论)
- HDU 2040 亲和数 -数论
- hdu 3092 Least common multiple(完全背包+数论)
- hdu1061(数论:快速幂取模)
- 【数论】HDU 4952 Number Transformation
- HDU 4983 Goffi and GCD(数论)
- hdu 5525 Product(数论)
- HDU 1495 非常可乐(数论)
- hdu 5317 RGCDQ(数论素筛)
- hdu 2552 三足鼎立 关于tan的数论
- HDU 3240 Counting Binary Trees 数论-卡特兰数
- [数论]HDU 2669 Romantic 扩展欧几里得算法
- hdu 2588 搞了好久的数论题 1到n的数与n的公约数大于m的数的个数
- HDU 1104 Remainder (POJ 2426 BFS+数论)
- hdu 5750 Dertouzos(数论)