题意:求在1-n之间所有任意两个数的的最大公因数的和。
解法:
先解释每一对互质数对对答案的贡献:
1.数对[a,b] 互质, 那对答案的贡献:ans[b]+=1;
2.那么不互质的时候,gcd(k*a,k*b)=k : 数对[k*a,k*b] ,对答案的贡献:ans[k*b] +=k*phi[b] ( phi[b]为欧拉函数值,即小于b的范围内gcd(a,b)==1,a值可取的个数,也可说是[?,b] 的互质对数)
综上:只需预处理出【1,4e6】的欧拉函数值phi[i],然后枚举互质对数的最大公约数k,每次更新对答案数组ans[i] 的贡献,再前缀和,即可
打表复杂度:O(NloglogN)
#include<bits/stdc++.h> #define ll long long using namespace std; int phi[4000006] ; int N=4000000; ll ans[4000006]; void phi_table() { for(int i=2;i<=N;i++) phi[i]=i; for(int i=2;i<=N;i++) { if(phi[i]==i) { for(int j=i;j<=N;j+=i) { phi[j]=phi[j]/i*(i-1); } } } } void getans() { for(int i=2;i<=N;i++) { for(int k=1;i*k<=N;k++) { ans[i*k]+=1ll*k*phi[i]; } } for(int i=2;i<=N;i++) { ans[i]+=ans[i-1]; } } int main() { phi_table();//欧拉打表 getans();//算贡献 前缀和 int n; while(~scanf("%d",&n)&&n) { printf("%lld\n",ans[n]); } }
GCD - Extreme (II) 欧拉函数打表
最新推荐文章于 2023-01-26 22:23:01 发布