【数论】hdu 6069 Counting Divisors

xiaoxiao2021-02-28  96

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[N],g[N]; 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] 的数; 参考队友的思路,代码,≧ ﹏ ≦
转载请注明原文地址: https://www.6miu.com/read-73043.html

最新回复(0)