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=l∑rd(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(唯一分解定理+因子数)