hdu 6069 Counting Divisors

Posted 声声醉如兰

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 6069 Counting Divisors相关的知识,希望对你有一定的参考价值。

题意:给出求L,R 之间的数的K次方的因子数之和

 

思路:打表求出1~10^6之间的素数,枚举[L,R]之间素数的倍数,然后按算数基本定理求出因子个数和。处理过后[L,R]之间的数要么是1,要么是一个素数,再次根据算数基本定理计算因子个数和。

 

技术分享
#include<bits/stdc++.h>
#define MAXSIZE 1000015
#define INF 0x3f3f3f3f
#define LL long long
#define MOD 998244353
using namespace std;

bool vis[MAXSIZE];
LL p[MAXSIZE],a[MAXSIZE],b[MAXSIZE];
int n,cns;

void GetPrime()
{
    cns = 1;
    memset(vis,false,sizeof(vis));
    vis[1] = true;
    for(int i=2;i<MAXSIZE;i++)
    {
        if(vis[i] == false)
        {
            p[cns++] = i;
            for(int j=i*2;j<MAXSIZE;j+=i)
            {
                vis[j] = true;
            }
        }
    }
}

int main()
{
    GetPrime();
    LL l,r,k,ans;
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&l,&r,&k);
        ans = 0;
        for(LL i=l;i<=r;i++)
        {
            a[i-l] = i; //记录这个数的值
            b[i-l] = 1; //记录正因子个数
        }

        for(int i=1;p[i]*p[i]<=r && i<=cns;i++) //枚举素数
        {
            LL j = l/p[i] + (l%p[i]!=0);
            for(j=j*p[i];j<=r;j+=p[i]) //枚举素数的倍数
            {
                LL sum = 0;
                while(a[j-l]%p[i] == 0)
                {
                    sum++;
                    a[j-l]/=p[i];
                }
                b[j-l] = (b[j-l]*((sum*k%MOD + 1)%MOD))%MOD; 
            }
        }

        for(LL i=l;i<=r;i++)
        {
            if(a[i-l] == 1)
                ans = (ans+b[i-l])%MOD;
            else
                ans = (ans+b[i-l]*(k+1)%MOD)%MOD;
        }

        printf("%lld\n",ans);
    }
    return 0;
}
View Code

 

以上是关于hdu 6069 Counting Divisors的主要内容,如果未能解决你的问题,请参考以下文章

hdu 6069 Counting Divisors(求因子的个数)

hdu 6069 Counting Divisors

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

第四场 hdu 6069 Counting Divisors (逆向思维)

区间筛2-17多校训练四 HDU6069 Counting Divisors

hdu6069 多校Counting Divisors