51 nod 1188 最大公约数之和 V2(狄利克雷卷积+线性筛法)
来源:互联网 发布:js返回顶部 编辑:程序博客网 时间:2024/06/06 05:41
题目大意:
给出T组n,
求
1<=n<=5000000,1<=T<=50000
吹水:
51 nod没良心,本来O(n log n)可以过的,可是不知为什么现在跑得这么慢,我把老曹的标再交了一次也T了3个点,于是强行推了O(n)的做法。
方法一:
先转换为:
线筛出φ,然后分块。
时间复杂度:
O(T
T了#17 - 25.
方法二:
设
如果我们能够快速求出f(i),求一个前缀和,就可以O(1)求解。
我们可以想到枚举gcd.
伪代码:
i = 1 to n j = 2 to n / if(i * j) += φ(j) * i
时间复杂度:O(n log n)
方法三:
其实f(i)可以直接线筛:
先看作:
之后再减回去。
这显然就是个狄利克雷卷积,所以f(i)是一个积性函数。
接着我们考虑i=p^q的时候怎么求
所以在线筛的时候还需要记录最小质因子的指数和最小质因子的幂。
方法三Code:
#include<cstdio>#define N 5000000#define fo(i, x, y) for(int i = x; i <= y; i ++)using namespace std;long long f[N + 5];int n, T, x[N + 5], y[N + 5], p[348514];bool bz[N + 5];int main() { f[1] = 1; fo(i, 2, N) { if(!bz[i]) p[++ p[0]] = i, x[i] = 1, y[i] = i, f[i] = 2 * i - 1; fo(j, 1, p[0]) { int k = i * p[j]; if(k > N) break; bz[k] = 1; if(!(i % p[j])) { x[k] = x[i] + 1; y[k] = y[i] * p[j]; f[k] = f[k / y[k]] * (x[k] * (y[k] - y[k] / p[j]) + y[k]); break; } x[k] = 1; y[k] = p[j]; f[k] = f[i] * f[p[j]]; } } fo(i, 1, N) f[i] = f[i - 1] + f[i] - i; for(scanf("%d", &T); T; T --) scanf("%d", &n), printf("%lld\n", f[n]);}
方法2Code:
#include<cstdio>#define fo(i, x, y) for(int i = x; i <= y; i ++)using namespace std;const int Maxn = 5000000;long long ans[Maxn + 5];int n, T, p[400000], phi[Maxn + 5];bool bz[Maxn + 5];int main() { phi[1] = 1; fo(i, 2, Maxn) { if(!bz[i]) p[++ p[0]] = i, phi[i] = i - 1; fo(j, 1, p[0]) { int k = i * p[j]; if(k > Maxn) break; bz[k] = 1; if(!(i % p[j])) { phi[k] = phi[i] * p[j]; break; } phi[k] = phi[i] * (p[j] - 1); } } fo(i, 1, Maxn) fo(j, 2, Maxn / i) ans[i * j] += i * phi[j]; fo(i, 2, Maxn) ans[i] = ans[i - 1] + ans[i]; printf("%d\n", ans[9]); for(scanf("%d", &T); T; T --) scanf("%d", &n), printf("%lld\n", ans[n]);}
方法1Code:
#include<cmath>#include<cstdio>#define ll long long#define fo(i, x, y) for(int i = x; i <= y; i ++)using namespace std;const ll Maxn = 5000000;int n, T, p[400000];ll phi[Maxn + 5];bool bz[Maxn + 5];int main() { phi[1] = 1; fo(i, 2, Maxn) { if(!bz[i]) p[++ p[0]] = i, phi[i] = i - 1; fo(j, 1, p[0]) { int k = i * p[j]; if(k > Maxn) break; bz[k] = 1; if(i % p[j] == 0) { phi[k] = phi[i] * p[j]; break; } phi[k] = phi[i] * (p[j] - 1); } } fo(i, 1, Maxn) phi[i] = phi[i - 1] + phi[i]; for(scanf("%d", &T); T; T --) { ll ans = 0; scanf("%d", &n); fo(i, 1, n) { int j = n / (n / i); ans += (phi[j] - phi[i - 1]) * (n / i) * (n / i + 1) / 2; i = j; } ans -= (ll) n * (n + 1) / 2; printf("%lld\n", ans); }}
阅读全文
1 0
- 51 nod 1188 最大公约数之和 V2(狄利克雷卷积+线性筛法)
- 51nod 1188 最大公约数之和 V2
- 51Nod-1188-最大公约数之和 V2
- 51 NOD 1188 最大公约数之和 V2(基础数论)
- [欧拉函数]51nod 1188 最大公约数之和 V2 题解
- 【51Nod 1188】最大公约数之和2
- 51nod 1040 最大公约数之和 (数学)
- [51nod1188]最大公约数之和 V2
- 51nod 1040:最大公约数之和
- [51nod]1040 最大公约数之和
- 【51Nod 1040】最大公约数之和
- 【51Nod 1040】最大公约数之和
- 51Nod-1040-最大公约数之和
- 51nod 1040 最大公约数之和
- 【51Nod 1040】 最大公约数之和
- 51nod-1040 最大公约数之和
- 51nod 1040 最大公约数之和
- 51nod 1040 最大公约数之和
- Ubuntu 16.04 compile JDK source code
- 【linux 常用命令】linux命令大全
- 第八课,线性表的链式存储结构
- [LeetCode 611] Valid Triangle Number
- Java学习笔记-《Java程序员面试宝典》-第四章基础知识-4.7输入输出流(4.7.1-4.7.3)
- 51 nod 1188 最大公约数之和 V2(狄利克雷卷积+线性筛法)
- java学习 jstl中if标签的使用
- mybatis一级缓存问题导致第二次查询结果出现变化
- 如何根据某个实体属性字段的不同值来设置另一个实体属性字段的值
- js:制作一个简易的计数器:根据输入的两个整数和运算符,进行计算,然后输出计算结果
- 深入理解Javascript的继承和原型链
- 【脚本语言系列】关于PythonWeb服务器Nginx+uWSGI,你需要知道的事
- React Native 自定义控件之验证码和Toast
- 合并果子(优先队列)