HDU6069 Counting Divisors欧拉筛法

Posted 海岛Blog

tags:

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

Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 6208 Accepted Submission(s): 2147

Problem Description
In mathematics, the function d(n) denotes the number of divisors of positive integer n.

For example, d(12)=6 because 1,2,3,4,6,12 are all 12’s divisors.

In this problem, given l,r and k, your task is to calculate the following thing :

( ∑ i = l r d ( i k ) ) m o d   998244353 \\left( {\\sum_{i=l}^{r}d(i^k)} \\right) mod  998244353 (i=lrd(ik))mod 998244353

Input
The first line of the input contains an integer T(1≤T≤15), denoting the number of test cases.

In each test case, there are 3 integers l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107).

Output
For each test case, print a single line containing an integer, denoting the answer.

Sample Input
3
1 5 1
1 10 2
1 100 3

Sample Output
10
48
2302

Source
2017 Multi-University Training Contest - Team 4

问题链接HDU6069 Counting Divisors
问题简述:(略)
问题分析:约数个数问题,不解释。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* HDU6069 Counting Divisors */

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
const int MOD = 998244353;

// 欧拉筛法
const int N = 1000000;
bool isprime[N + 1];
int prime[N / 3], pcnt = 0;
void eulersieve(void)
{
    memset(isprime, true, sizeof(isprime));

    isprime[0] = isprime[1] = false;
    for(int i = 2; i <= N; i++) {
        if(isprime[i])
            prime[pcnt++] = i;
        for(int j = 0; j < pcnt && i * prime[j] <= N; j++) {  //筛选
            isprime[i * prime[j]] = false;
            if(i % prime[j] == 0) break;
        }
    }
}

LL num[N + 1], sum[N + 1];  // sum[i]表示l+i约数个数

int main()
{
    eulersieve();

    int t, k;
    scanf("%d", &t);
    while (t--) {
        LL l, r;
        scanf("%lld%lld%d", &l, &r, &k);

        int end = int(r - l);
        for (int i = 0; i <= end; i++) {
            num[i] = l + i;
            sum[i] = 1;
        }

        for (int i = 0; i < pcnt; i++) {
            if (prime[i] * prime[i] > r) break;
            LL t = l;
            if (t % prime[i]) t = (t / prime[i] + 1) * prime[i];
            for (LL j = t; j <= r; j += prime[i]) {
                int cnt = 0, idx = int(j - l);
                while (num[idx] % prime[i] == 0)
                    cnt++, num[idx] /= prime[i];
                sum[idx] = (sum[idx] * (cnt * k + 1) % MOD) % MOD;
            }
        }

        LL ans = 0;
        for (int i = 0; i <= end; i++) {
            if(num[i] > 1)
                sum[i] = (sum[i] * (k + 1)) % MOD;
            ans = (ans + sum[i]) % MOD;
        }

        printf("%lld\\n", ans);
    }

    return 0;
}

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

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

hdu 6069 Counting Divisors

hdu6069 多校Counting Divisors

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

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

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