2017 Multi-University Training Contest 4 1003

来源:互联网 发布:卖家对淘宝差评回复 编辑:程序博客网 时间:2024/06/08 04:33

题意:让你求【L,R】区间的每个数i的k次方的因子数和%998244353。

解法:首先要知道一个数的因子数,是等于由这个质因子的次方+1相乘起来等到的。n=p_1^{c_1}p_2^{c_2}...p_m^{c_m}n=p1c1p2c2...pmcm,则d(n^k)=(kc_1+1)(kc_2+1)...(kc_m+1)d(nk)=(kc1+1)(kc2+1)...(kcm+1)如果是k次方的话就把这个k乘到质因子的次方上去就行了,关键在于怎么枚举区间,首先枚举小于等于根号R区间的质数p,再枚举【L,R】区间所有p的倍数,计算他的因子数,剩下的就是超过根号R的质数,只可能为0或者1。


#include <stdio.h>#include<math.h>#include<cstring>#include<iostream>#define LL long longconst LL mod = 998244353;const int MAX_N = 1e6+10;using namespace std;LL l,r,k,ans[MAX_N],f[MAX_N];int isp[MAX_N],cnt;LL pri[MAX_N];void Euler(LL p){    LL t = 0;    for(LL i = l/p*p;i <= r;i+=p)    {        if(i >= l)        {            t = 0;            while(f[i-l]%p==0)            {                t++;                f[i-l]/=p;            }            ans[i-l] = ans[i-l]*(t*k+1)%mod;        }    }}void init(){    cnt = 0;    memset(isp,0,sizeof(isp));    isp[0] = 1; isp[1] = 1;    for(int i = 2;i < MAX_N;i++)    {        if(!isp[i])            pri[cnt++] = i;        for(int j = 0;j < cnt&&pri[j]*i < MAX_N;j++)        {            isp[i*pri[j]] = 1;            if(i%pri[j] == 0) break;        }    }}int main(){    int T;    init();    //cout<<cnt<<endl;    scanf("%d",&T);    while(T--)    {        scanf("%lld%lld%lld",&l,&r,&k);        LL d = r-l;        for(int i = 0;i <= d;i++)        {            f[i] = i+l;            ans[i] = 1;        }        for(int i = 0;i < cnt;i++)        {            if(pri[i]*pri[i] > r) break;            Euler(pri[i]);        }        LL ANS = 0;        for(int i = 0;i <= d;i++)        {            if(f[i] > 1)                ans[i] = ans[i]*(k+1)%mod;            ANS = (ANS+ans[i])%mod;        }        printf("%lld\n",ANS);    }    return 0;}


原创粉丝点击