求所有整数 1 到 N 的最大奇数除数之和
Find the sum of the greatest odd divisor of all integers 1 through N
本文关键字:整数 更新时间:2023-10-16
我得到一个正整数N.f(N(是N的最大奇数除数。
求和 (f(1(+f(2(+f(3(+....f(N((%m.
如果 N 是 10^18 阶,而 m 可以达到 10^9,那么更快的算法应该是什么?
暴力破解算法示例:
int sum=0;
int a[n+1];
for(int i=1;i<=n;i++){
if(i%2!=0)
a[i] = i;
else
a[i] = a[i/2];
}
for(int i=1;i<=n;i++){
sum+=a[i];
}
cout<<sum;
范围 [1,N] 中奇数的总和是奇数数数的平方,或 ((N+1(/2(^2,其中 '/' 表示整数除法。我们称之为 p(N(。
我们仍然需要找到范围 [1,N] 中偶数的最大奇数除数之和。我们可以将范围内的偶数除以除以它们的最大幂 2。
For 1 power of 2: p(N/2)
For 2 powers of 2: p(N/4)
For 3 powers of 2: p(N/8)
等。。。
即, f(N( = p(N( + p(N/2( + p(N/4( + p(N/8( + ...
以下是 N = 1, 2, ..., 20 的结果:
N, f(N)
1, 1
2, 2
3, 5
4, 6
5, 11
6, 14
7, 21
8, 22
9, 31
10, 36
11, 47
12, 50
13, 63
14, 70
15, 85
16, 86
17, 103
18, 112
19, 131
20, 136
无耻地采用戴夫的解决方案,但添加了代码。
找到:
F(N) mod M = (f(1) + f(2) + ... + f(N)) mod M
鉴于:
1. f(n) = greatest odd divisor of n
1a. f(n) = n, for all odd n
1b. f(n) = f(n/2), for all even n
(note, this is recursive: f(n) = f(n/2) = f(n/4) = ... until we hit an odd number)
2. p(n) = sum of all odd numbers less than or equal to n
2a. p(n) = (number of odd numbers less than or equal to n) squared
3. F(N) = f(1) + f(2) + ... + f(N)
4. 1 <= N <= 10^18
5. 1 <= M <= 10^9
然后:
F(N) = p(N) + [f(2) + f(4) + ... + f(largest even not > N)]
= p(N) + [f(1) + f(2) + ... + f(N/2)]
= p(N) + F(N/2)
= p(N) + p(N/2) + p(N/4) + ...
and
F(N) mod M = (p(N) mod M + p(N/2) mod M + ...) mod M
p(N)
具有复杂性O(1)
,递归F(N)
具有复杂性O(log N)
这将比可能O(N log N)
的蛮力方法快得多(我相信。有人验证了这一点(。
以下C++代码完成此算法
#include <iostream>
using value_type = unsigned long long;
value_type p_N_mod_M(value_type N, value_type M)
{
// nom := _N_umber of _O_dd numbers not greater than N, _M_od-M
value_type nom = ((N + 1) / 2) % M;
return (nom * nom) % M;
}
value_type F_N_mod_M(value_type N, value_type M)
{
if (N == 0) return 0;
if (N == 1) return 1;
return (p_N_mod_M(N, M) + F_N_mod_M(N / 2, M)) % M;
}
int main()
{
value_type N, M;
std::cout << "Calculates F(N) mod M = (f(1) + f(2) + ... + f(N)) mod M,n"
"where f(n) is the greatest odd divisor of n.n"
" [1 <= N <= 10^18]; [1 <= M <= 10^9]n"
"------------------------------------------------------------------n"
"Enter N followed by M: ";
std::cin >> N >> M;
std::cout << "nF(" << N << ") mod " << M << " = " << F_N_mod_M(N, M) << "n";
}
示例输出:
Calculates F(N) mod M = (f(1) + f(2) + ... + f(N)) mod M,
where f(n) is the greatest odd divisor of n.
[1 <= N <= 10^18]; [1 <= M <= 10^9]
------------------------------------------------------------------
Enter N followed by M: 20 200
F(20) mod 200 = 136
----
Calculates F(N) mod M = (f(1) + f(2) + ... + f(N)) mod M,
where f(n) is the greatest odd divisor of n.
[1 <= N <= 10^18]; [1 <= M <= 10^9]
------------------------------------------------------------------
Enter N followed by M: 20 135
F(20) mod 135 = 1
相关文章:
- 如何反转整数参数包
- enum是C++中的宏变量还是整数变量
- 努力将整数转换为链表。不知道我在这里做错了什么
- 整数不会重复超过随机数
- 在C++中手动调整数组大小
- 检查输入是否不是整数或数字
- C++使用整数的压缩数组初始化对象
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何只允许用户输入正整数
- 如何在c++中从文本文件中逐行读取整数
- C++:如何循环通过向量中的整数元素
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 序列化,没有库的整数,得到奇怪的结果
- 在一定长度后从数组中打印时缺少整数
- std::当在256字节边界上写入整数时,流的奇怪行为
- 内联程序集printf将整数解释为地址
- 是否基于数组B整数打印数组A中的整数
- 如何在C++中将整数转换为其数字数组