HDU 6069 Counting Divisors

来源:互联网 发布:mac双系统win8 编辑:程序博客网 时间:2024/06/05 06:14

HDU 6069 Counting Divisors

原题连接:
http://acm.hdu.edu.cn/showproblem.php?pid=6069

应该是比较简单的。(开始一直怀疑自己读错题了)

除数函数是积性的。

τ0(n)=i|ni0

τ0(n)=i=1r(ai+1)

其中n的质因数分解形式为:

n=i=1rPaii

明显:

nk=(i=1rPaii)k=i=1rPaiki

τ0(nk)=i=1r(kai+1)

对区间[l,r]质因数分解即可。

#include <iostream>#define MAXN 1001106using namespace std;typedef long long LL;const LL mod=998244353;LL A[MAXN+100];LL B[MAXN+100];LL Prim[MAXN*2];bool vis[MAXN*2];LL deep;void prim(){    for(int i=2,s=MAXN*2;i<s;i++)    {        if(vis[i])continue;        Prim[deep++]=(LL)i;        if(i>MAXN)break;        for(int j=i+i;j<s;j+=i)    vis[j]=true;    }}int main (){    prim();    int T;    scanf("%d",&T);    while(T--)    {        LL l,r,K;        cin>>l>>r>>K;        int si=(int)(r-l)+1;        for(int i=0;i<si;i++)        {            B[i]=l+(LL)i;            A[i]=1;        }        LL ans=0;        for(LL i=0;i<deep;i++)        {            LL k=Prim[i];            for(LL di=(k-l%k)%k; di<si ; di+=k)            {                LL a=0;                while(B[di]%k==0)                {                    B[di]/=k;                    a++;                }                A[di]=A[di]*(K*a+1);                if(A[di]>mod)A[di]%=mod;            }        }        for(LL i=0;i<si;i++)        {            if(B[i]>1)A[i]=A[i]*(K+1)%mod;            ans+=A[i];            if(ans>=mod)ans-=mod;        }        cout<<ans%mod<<endl;    }    return 0;}
原创粉丝点击