hdu6069Counting Divisors(约数个数定理)

来源:互联网 发布:ae for mac破解版下载 编辑:程序博客网 时间:2024/05/22 13:10

题意:

给你l,r,k三个整数,求区间[l,r]内每个数 的k次方的因子总数。

思路:

枚举根号r内的质数,求出每个质数在区间内贡献值,利用约数个数定理求因子总数,注意处理区间内大于根号r的质数。

代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;typedef long long LL;const int mod = 998244353;const int maxn = 1000000+10;LL prime[maxn],sum[maxn],num[maxn];int cnt = 0;void getPrime(){    memset(prime,0,sizeof(prime));    for(int i = 2;i<maxn;i++)    {        if(!prime[i])        {            prime[cnt++] = i;            for(int j = i*2;j<maxn;j+=i)                prime[j] = 1;        }    }}int main(){    int t;    scanf("%d",&t);    getPrime();    while(t--)    {        LL l,r,k;        scanf("%lld%lld%lld",&l,&r,&k);        for(LL i = l;i<=r;i++)            num[i-l] = i,sum[i-l] = 1;        for(int i = 0;i<cnt;i++)        {            LL flag = l%prime[i];            LL fir;            if(!flag)            {                fir = l;            }            else            {                fir = l-flag+prime[i];            }            for(LL j = fir;j<=r;j+=prime[i])            {                int ti = 0;                while(num[j-l]%prime[i]==0) ti++,num[j-l]/=prime[i];                sum[j-l] *= k*ti+1;                sum[j-l] %= mod;            }        }        LL ans = 0;        for(LL i = l;i<=r;i++)        {            if(num[i-l]!=1)                sum[i-l] = sum[i-l]*(k+1)%mod;            ans += sum[i-l];            ans %= mod;        }        printf("%lld\n",ans);    }    return 0;}

原创粉丝点击