1. 程式人生 > >hdu--6069--Counting Divisors

hdu--6069--Counting Divisors

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 998244353;
const int maxn = 1000009;
bool Isprime[maxn];       ///素數表1
LL prime[maxn];           ///素數表2
LL a1[maxn], sum[maxn];
int cnt;
LL l, r, k;
void Prime()
{
    ///列印素數表,Isprime[ ]和prime[ ];
    cnt = 0;
    memset(Isprime, true
sizeof(Isprime));
    Isprime[1] = false;
    for(int i = 2 ; i < maxn ; i++)
    {
        if(Isprime[i])
        {
            prime[cnt++] = i;
            for(int j = 2 ; i * j < maxn ; j++)
                Isprime[i * j] = false;
        }
    }
}

int main()
{
    Prime();
    int t;
    scanf("%d"
, &t);
    while(t--)
    {
        scanf("%lld%lld%lld", &l, &r, &k);
        for(int i = 0; i <= r - l; i++)
        {
            sum[i] = 1///sum是要做乘法的,初值為1
            a1[i] = i + l; ///對應儲存l--r的值;
        }

        for(int i = 0; i < cnt; i++)
        {
            int x;
            if
(l % prime[i] != 0)
                x = 1;
            else if(l % prime[i] == 0)
                x = 0;
            LL fir = (l / prime[i] + x) * prime[i]; ///fir是從l開始第一個能整除prime[i]的

            for(LL j = fir; j <= r; j += prime[i]) ///每個j都能整除prime[i]
            {
                LL res = 0;
                while(a1[j - l] % prime[i] == 0)
                {
                    res++;
                    a1[j - l] /= prime[i];
                }///一直除下去,讓數變小,找到prime[i]的冪值
                sum[j - l] = (sum[j - l] * ((res * k + 1) % mod)) % mod; ///sum[j-l]乘一下,取模
            }
        }
        LL ans = 0;
        for(int i = 0; i <= r - l; i++)
        {
            if(a1[i] != 1)
            {
                sum[i] = (sum[i] * (k + 1)) % mod; ///經過一系列除法沒除到1,說明1e6內的素數分解不了,那麼它就是一個大素數
            }

            ans = (ans + sum[i]) % mod;
        }
        printf("%lld\n", ans);
    }

    return 0;
}