uva11426
来源:互联网 发布:mac如何打开mpp文件 编辑:程序博客网 时间:2024/06/07 00:48
可以化成简单的s[n] = s[n - 1] + f[n]
关键在于求f[n] = gcd(1, n) + gcd(2, n) + ... + gcd(n - 1, n)
直接裸求的话肯定会超时。可以把上面的和按和n的约数来分类。
约数为1,2,3...
那么结果就为sums{i * g(i, n)};
g(i, n)表示和n约数为i的数的个数、相当于求gcd(x / i, n /i) == 1的数的个数,就是phi[n / i];
但是如果顺序枚举的话时间会很慢,不如反过来,求约数开始枚举。
约数为1,约数为2...
求出f[n]即可。
#include <cstdio>#include <string.h>#include <iostream>const int MAX_NUMBER = 4000000;long long value[MAX_NUMBER + 2], phi[MAX_NUMBER + 2], f[MAX_NUMBER];void getPhiTable() {memset(phi, 0, sizeof(phi));phi[1] = 1;for (int i = 2; i <= MAX_NUMBER; i++) {if (!phi[i]) {for (int j = i; j <= MAX_NUMBER; j += i) {if (!phi[j]) {phi[j] = j;}phi[j] = phi[j] / i * (i - 1);}}}}void getF() {for (int i = 1; i <= MAX_NUMBER; i++) {for (int j = i * 2; j <= MAX_NUMBER; j += i) {f[j] += i * phi[j / i];}}}int number;int main() {getPhiTable();getF();value[2] = 1;for (int i = 3; i <= MAX_NUMBER; i++) {value[i] = value[i - 1] + f[i];}while (scanf("%d", &number) != EOF) {if (!number) {break;}std::cout << value[number] << std::endl;}return 0;}
- uva11426
- uva11426
- UVA11426
- UVa11426
- uva11426(数学题)
- UVA11426:GCD
- UVA11426 GCD
- UVA11426 GCD
- UVA11426 GCD
- GCD Extreme(II) UVA11426
- uva11426 GCD - Extreme (II)
- uva11426(欧拉函数)
- uva11426(gcd + 欧拉函数)
- 例题2.9 最大公约数之和 UVa11426
- UVALive5964 LCM Extreme && UVA11426 GCD
- UVA11426 FZU1969 51NOD1188 线性欧拉筛法+筛法
- UVA11426 GCD - Extreme (II) 欧拉函数`扩展欧几里德应用
- 欧拉函数与数论的结合UVA11426
- Java:使用匿名内部类在方法内部定义并启动线程
- 浮点算术
- Struts2.x+JFreeChart搭建框架出错(四)
- 用c写的游戏——扫雷
- HTML5新特性
- uva11426
- poj2891一次线性模余定理
- STM32的can现场总线实验心得
- 点击OK时View类获取对话框的编辑框的值的方法
- 冯诺依曼与哈佛结构
- STM32访问外部存储器-NOR-Flash
- 类加载器
- 新旧系统切换与项目小结
- Java 对数据库表名的解析