HDU 6069 Counting Divisors

来源:互联网 发布:suse linux vsftp 编辑:程序博客网 时间:2024/06/05 02:53

题意:

求l~r所有因子约数K次方的和

思路:

对于l~r 很大, 我们枚举每一个素数对于他的贡献,使得每一个数字尽可能除包含的素数。

素数唯一分解定理

d(nk)=(kc1+1)(kc2+1)...(kcm+1)

#include <stdio.h>#include <cstring>#include <algorithm>#include <iostream>#include <cmath>using namespace std;const long long mod=998244353;const int maxn=1000005;int prime[maxn];int cnt=0;int vis[maxn];typedef long long ll;ll res[maxn];ll a[maxn];void init(){    for(int i=2;i<=maxn;i++)    {        if(!vis[i])        {            vis[i]=1;            cnt++;            prime[cnt]=i;            for(int j=i;j<=maxn;j+=i)            {                vis[j]=1;            }        }    }}int main(){    init();    int cas;    scanf("%d",&cas);    while(cas--)    {        ll l,r,k;        long long ans=0;        scanf("%lld%lld%lld",&l,&r,&k);        for(ll i=l;i<=r;i++)        {            res[i-l]=1;            a[i-l]=i;        }        for(ll i=1;prime[i]<=r&&i<=cnt;i++)        {            ll t=l/prime[i]*prime[i];            while(t<l)                t+=prime[i];            for(ll j=t;j<=r;j+=prime[i])            {                ll tot=0;                while(a[j-l]%prime[i]==0)                {                    tot++;                    a[j-l]/=prime[i];                }                res[j-l]=res[j-l]*(tot*k%mod+1)%mod;            }        }        for(ll i=l;i<=r;i++)        {            if(a[i-l]!=1)                res[i-l]=res[i-l]*(k+1)%mod;            ans=(ans+res[i-l])%mod;        }        printf("%lld\n",ans);    }}


d(nk)=(kc1+1)(kc2+1)...(kcm+1)
原创粉丝点击