Pillai's arithmetic function 算法实现 --------------------------------附 河南省2017多校联萌5
来源:互联网 发布:红学会 知乎 编辑:程序博客网 时间:2024/06/06 20:56
Pillai's arithmetic function
定义:求前n个数分别和n的最大公约数的和。详细见维基百科(下图)
那么如何高效求出函数值P(n)呢?且n很大,例如 n := 1:1e11。(取10^11是为了秒出结果,因为开方后不超过百万)
这个数论问题,具体实现需要用到因数分解,线性素数筛,质因数分解,欧拉函数,也得知道这个公式。
1、先因数分解,我算了下,10^11的因数才只有144个。
2、然后就是求单个欧拉数,不可能用线性欧拉筛,存不下,也没时间。只能需要哪个求哪个(在线算法)。
单个欧拉数求法,直接用定义。百度百科:
3、要快速求出欧拉数,就需要质因数分解,求出素因数。这求需要线性素数筛求p[i].虽然n很大,但是开方一次就不过百万了。
4、得到素因数,进而求出欧拉数,再进而求出 Pillai's arithmetic function 值。
输入n;输出 P[n]。( Pillai's arithmetic function )
#define _CRT_SECURE_NO_WARNINGS#include <cstdio>#include <vector>#include <cstring>#include <cmath>using namespace std;long long v[150]; //1e11const int N = 320000;bool vis[N + 1];int p[27610], cnt_p; //存素数 27608int getPrime(int n) {memset(vis, 1, sizeof vis);int cnt = 0;for (int i = 2; i <= n; ++i) {if (vis[i]) p[cnt++] = i;for (int j = 0; j < cnt && (i * p[j] <= n); ++j) {vis[i * p[j]] = 0;if (i % p[j] == 0) break;}}return cnt;}vector <long long> work(long long num) {vector<long long> vec;for (int i = 0; i < cnt_p; ++i) {if (num % p[i] == 0) {vec.push_back(p[i]);while (num % p[i] == 0) num /= p[i];}if (num <= 1) break;} //得到了素因数if (num > 1) vec.push_back(num);return vec;}long long phi(long long n) {long long res = n;vector<long long> v = work(n);for (int i = 0; i < v.size(); ++i) {res = res / v[i] * (v[i] - 1);}return res;}int main(){cnt_p = getPrime(N);//cout << phi(37) << endl;long long n;while (~scanf("%lld", &n)) {if (n <= 1) { printf("%lld\n", n); continue; }long long m = sqrt(n + 0.5), sz = 0;v[sz++] = 1;for (int i = 2; i <= m; ++i) {if (n % i == 0) {v[sz++] = i;//存因数v[sz++] = n / i;}}if (m * m == n) sz--; if (n > 1) v[sz++] = n;long long res = 0;for (int i = 0; i < sz; ++i) {res += v[i] * phi(n / v[i]);}printf("%lld\n", res);}return 0;}
河南省2017多校联萌五
上面介绍的是A题。
B题是调和级数求和。当n不大时,直接用定义,当n足够大时,精度变化就不大了,直接用近似算法:
sum(n) =
log
(n + 0.5) + phi; //
const
double
phi = 0.57721566490153286060651209;
C题二分,注意结果要求尽量小,所以结果只可能以5或0结尾。
H题,最小生成树。prim算法或者kruskal算法。我用的kruskal算法。
D题过的人也不少,我卡死在了A题。因为质因数筛选时边界问题没处理好。打饭排队时想到的bug.
阅读全文
0 0
- Pillai's arithmetic function 算法实现 --------------------------------附 河南省2017多校联萌5
- date arithmetic / map function
- I - Dirichlet's Theorem on Arithmetic Progressions(1.5.5)
- I - Dirichlet's Theorem on Arithmetic Progressions(1.5.5)
- 【算法】5 传说中的快排是怎样的,附实现示例
- arithmetic 冒泡算法
- 算法(arithmetic)
- pointer to a function used in arithmetic
- 实现MidiFive arithmetic
- 排序算法吐血整理-附java实现
- Java 常用排序算法 附java实现
- 河南省多校联萌(四)
- 河南省多校联萌(四)
- 河南省多校联萌(四)
- 探索Lua5.2内部实现:虚拟机指令(5)Arithmetic
- 2017 河南省赛感想
- Arithmetic Encoding(压缩算法)
- 算法第七周 Arithmetic Slices
- Ajax上传图片以及上传之前先预览
- 推荐一些优秀的博客
- 关于 c++ 内存泄漏
- java private public protect 等访问权限
- 构造函数--继承
- Pillai's arithmetic function 算法实现 --------------------------------附 河南省2017多校联萌5
- Tomcat8–模板配置记录
- java 枚举类型 enum (示例程序)
- 【ISA的胡策】训练8.25(博弈)
- iOS开发中的frame和bounds
- 清华大学2002年机试-杨辉三角形-1073
- 2017-08-25 DBA日记,telegraf、influxDB、Grafana的安装与基本使用
- 如何使用Eclipse搭建Spring框架
- Python 时间