hdu--6069--Counting Divisors
来源:互联网 发布:淘宝家具店招图片 编辑:程序博客网 时间:2024/05/29 19:50
Counting Divisors
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)Total Submission(s): 2947 Accepted Submission(s): 1084
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, givenl,r and k , your task is to calculate the following thing :
(∑i=lrd(ik))mod998244353
For example,
In this problem, given
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 are3 integers l,r,k(1≤l≤r≤1012,r−l≤106,1≤k≤107) .
In each test case, there are
Output
For each test case, print a single line containing an integer, denoting the answer.
Sample Input
31 5 11 10 21 100 3
Sample Output
10482302
Source
2017 Multi-University Training Contest - Team 4
题意:d(i)表示i的因子个数;给出l,r,k。求出(∑i=lrd(ik))mod998244353
解题思路:根据约数个数定理得出:n=p1^c1*p2^c2*.....*pn^cn;
可得:d(n)=(c1+1)*(c2+1)*.....*(cn+1);
进一步:d(n^k)=(c1*k+1)*(c2*k+1)*.....*(cn*k+1);
d(n)里的n取值范围为1--10^12;要判断n是不是素数,只需要打1--10^6的素数表。
如果n是素数,那么他的贡献为(k+1),如果n不是素数,就用表内的素数进行分解;
具体做法是遍历已经打印好的素数表prime[maxn],另外开一个数组a,存放l到r,对应的下标为0到r-l;
遍历prime[i]时,先找到a数组内第一个能整除prime[i]的元素a[j],并用prime[i]对它进行分解,直到除不尽。
此后,每次a的下标加prime[i]个,做到消除a内以prime[i]为因子的数。
最后只要 a[i]不等于1,则其一定剩下的是一个大于 10^6的素数了。
代码:
C++ Code
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#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;
}
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;
}
阅读全文
0 0
- hdu 6069 Counting Divisors
- [HDU]6069 Counting Divisors
- HDU 6069 Counting Divisors
- HDU 6069 Counting Divisors
- HDU-6069 Counting Divisors
- HDU 6069 Counting Divisors
- HDU-6069 Counting Divisors
- HDU 6069 Counting Divisors
- HDU 6069 Counting Divisors
- hdu 6069 Counting Divisors
- HDU 6069 Counting Divisors
- hdu--6069--Counting Divisors
- HDU-6069 Counting Divisors
- HDU-6069 Counting Divisors
- HDU 6069 Counting Divisors
- hdu 6069Counting Divisors 数学
- hdu 6069 Counting Divisors(筛法)
- 【数论】hdu 6069 Counting Divisors
- Qt 设置定时器,label自动隐藏
- hdu 6070 Dirt Ratio(线段树+二分答案)
- 数据的替换
- laravel使用多个数据库连接
- C++ 函数模板 实例化和具体化
- hdu--6069--Counting Divisors
- hdu1556 Color the ball
- tf.contrib.legacy_seq2seq.basic_rnn_seq2seq 函数 example 最简单实现
- java 根据给定的日期得到给定日期的前一天的日期
- Flume使用大全之kafka source-kafka channel-hdfs
- jquery Ajax请求本地json
- Oracle基础 用户管理
- spring mvc 设置@Scope("prototype")
- 将tensorflow的backend设置为theano的backend