欧拉函数,筛法(最大公约数之和——极限版II,UVA 11426)
来源:互联网 发布:unity3d 刚体穿透 编辑:程序博客网 时间:2024/06/08 08:47
看到数据范围,大概就知道是O(nlogn)了。
然后一开始尝试用筛法来做,有一些细节没办法处理好,想要处理好至少要O(n^2logn),还不如O(n^2)。
注意啊我的方法是错的,只是讲一下,别看。
我的方法就是ans[j]表示∑gcd(i,j),i<j。
然后s[i]=s[i-1]+ans[i]。
s[n]就是答案。
怎么求ans[j]呢。就是用筛法。
因为 ans[j]=∑gcd(i,j),i<j。
枚举i以及i的倍数j。这时gcd(i,j)=i。
然后ans[i]+=(j-i)/i*(i-f(i,j));
这个式子就是让每个gcd(i,j)都等于i,然后后面筛选时再部分修改。
f(i,j)就是不等于i的gcd(i,j)。表示之前错误的gcd(i,j)。
(i-f(i,j))的意思就是把错误的gcd(i,j)修改成i的修改值。
(j-i)/i就是有这么多错误的gcd。
相乘就是总的需要的修改值。更新一下ans[j]就好了。
这个方法只能得到一个近似的答案,因为每个错误的gcd(i,j)需要的修改值是不同的,不能用f(i,j)来代表全部,必须要O(n)枚举才能知道每个错误的gcd(i,j)的值。需要增加时间复杂度,这就超时了。然后就不知道该怎么处理了。
事实上我的思路应该更清晰一点的,在思考一道题的过程中会有非常多的想法,其中有很多错误的思路,虽然最后往往都能找对大方向,但是还像盲人摸象,思路太杂,互相干扰,最后在细节上失败。所以说如果有队友能一起讨论,那就能帮你缕清很多灰蒙蒙的地方,而有时候单单自己想会很迷。当然自己一定要学会自己独立解决问题,个人实力是队伍的尖刀,不要太依赖队友。
已经能想到用筛法以及求和了,不放把细节定义得更清楚一点,而不是觉得差不多是这个意思就好,否则就会进入迷的状态。
ans[j]=∑gcd(i,j),i<j。直接算就是朴素算法,想要另辟蹊径就得重新分类然后求和。
不妨设i是j的因数,设g(i,j)表示小于j的数x中满足gcd(x,j)=i的x的个数。(感觉最近接触了很多这种状态定义的方法,一维表示小于,二维表示确定的值,状态转移也容易实现。)
那么就枚举因数i咯,ans[j]=∑i*g(i,j),其中i是j的因数。
枚举因数时间复杂度是O(sqrt(j)),比O(j)好。
而g(i,j)该怎么求呢?状态转移方程不是那么好找。
我们应该学会发现一些特点,那就是j是i的倍数,而我们要找gcd(x,j)=i。那x肯定是i的倍数,其实就是找gcd(x/i,j/i)=1的x的个数,这不就是phi[j/i]吗。可以预处理然后O(1)求得。
然而还是不够快,但是关于枚举因数,我们可以用筛法来优化。
枚举因数i和它的倍数j,更新ans[j]就好了。
预处理O(nlogn)。
筛法O(nlogn)。
总时间复杂度O(nlogn)。
代码
#include<bits/stdc++.h>#define maxn 4000010using namespace std;typedef long long ll;ll phi[maxn];void phi_table(){ phi[1]=1; for(ll i=2;i<=4000000;i++) if(!phi[i]) for(ll j=i;j<=4000000;j+=i) { if(!phi[j]) phi[j]=j; phi[j]=phi[j]/i*(i-1); }}ll f[maxn];ll s[maxn];void init(){ for(ll i=1;i<=4000000;i++) for(ll j=i+i;j<=4000000;j+=i) f[j]+=i*phi[j/i]; for(ll i=1;i<=4000000;i++) s[i]=s[i-1]+f[i];}int main(){ phi_table(); init(); ll N; while(scanf("%I64d",&N)==1&&N) printf("%I64d\n",s[N]); return 0;}
- 欧拉函数,筛法(最大公约数之和——极限版II,UVA 11426)
- NYOJ 题目569最大公约数之和(欧拉函数,数学)
- 最大公约数之和(数据过大)欧拉函数
- 51nod-1040-最大公约数之和(欧拉函数)
- 51NOD 1040 最大公约数之和(欧拉函数 + 转化)
- 51nod 1040 最大公约数之和(欧拉函数)
- POJ2480(欧拉函数求最大公约数之和)
- nyoj569 最大公约数之和(欧拉函数+技巧)
- 51nod1040 最大公约数之和 (欧拉函数 )
- 【51nod1040】【最大公约数之和】【欧拉函数】
- 51Nod1040 最大公约数之和 欧拉函数
- UVA 11426 GCD - Extreme (II) (欧拉函数)
- UVA 11426 GCD - Extreme (II)(欧拉函数)
- UVA 11426 GCD - Extreme (II)(欧拉函数)
- 51NOD 1040 最大公约数之和(分析 + 欧拉函数)
- 51nod-1040-1040 最大公约数之和(欧拉函数)
- 51NOD 1040 1040 最大公约数之和 数论 欧拉函数
- 【51nod】1040 最大公约数之和 欧拉函数
- CodeForces 719E Sasha and Array 【线段树】【快速矩阵幂】
- Hbase协处理器(Coprocessor)
- 自学iOS开发系列----C语言(数组)
- java.security.InvalidKeyException: Illegal key size
- java获取当前时间
- 欧拉函数,筛法(最大公约数之和——极限版II,UVA 11426)
- linux系统下安装 jdk、tomcat、jetty 总结
- 注解的方式配置springMVC
- 11月17日——离noip还有2天[绯弹的亚里亚]
- C++学习笔记(四)
- 求素数
- makefile详细介绍,没太看懂
- 软件工程--设计阶段
- 关于矩阵之间的四则运算:gemm()函数