HDU 6069 Counting Divisors(唯一分解定理+因子数)

时间:2021-11-20 13:08:26

http://acm.hdu.edu.cn/showproblem.php?pid=6069

题意:

HDU 6069 Counting Divisors(唯一分解定理+因子数)

思路:

根据唯一分解定理,$n={a_{1}}^{p1}*{a2_{}}^{p2}...*{a_{m}}^{pm}$,那么n的因子数就是HDU 6069 Counting Divisors(唯一分解定理+因子数)

n的k次方也是一样的,也就是p前面乘个k就可以了。

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

到最后如果一个数没有变成1,那就说明这个数是大于1e6的质数。(它就只有0和1两种选择)

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn=1e6+;
const int mod=; int n;
int cnt=;
int primes[maxn];
int vis[maxn]; void get_primes()
{
int m=sqrt(maxn+0.5);
for(int i=;i<=m;i++)
{
if(!vis[i])
{
for(int j=i*i;j<=maxn;j+=i)
vis[j]=;
}
}
for(int i=;i<=maxn;i++)
if(!vis[i]) primes[cnt++]=i;
} ll l, r, k;
ll sum[maxn], num[maxn]; int main()
{
//freopen("in.txt","r",stdin);
get_primes();
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld",&l,&r,&k); ll ans=;
for(ll i=l;i<=r;i++) {sum[i-l]=;num[i-l]=i;} for(int i=; i<cnt && primes[i]*primes[i]<=r; 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]==)
{
int res=;
while(num[j-l]%primes[i]==)
{
res++;
num[j-l]/=primes[i];
}
sum[j-l]=(sum[j-l]*(((ll)res*k+))%mod)%mod;
}
}
} for(ll i=l;i<=r;i++)
{
if(num[i-l]!=) sum[i-l]=(sum[i-l]*(k+))%mod; //大于1e6的质数
ans=(ans+sum[i-l])%mod;
}
printf("%lld\n",ans);
}
return ;
}