20190811模拟赛T4 最大公约数 解题报告
根据欧拉函数的定义,令 是
的第
个因数,且满足
。 则这样的x
有 个, 两边同乘以
, 即可推出
。(显然)
以内与
的最大公约数为
的数有
个。
与所有小于
的数的最大公约数之和为
for(i=1;i<=n;i++) //枚举n的约数
if(n%i==0) f[n]+=phi[n/i]*i; 外层还要枚举每个数字,故时间复杂度为
可惜要T。
那么就可以优化一下,枚举那个公因数,累加答案。
见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#define maxn 1000000
using namespace std;
int n;
long long phi[1000001],f[1000001];
void Si()
{
for(int i=2;i<=maxn;i++) phi[i]=i;
for(int i=2;i<=maxn;i++)
if(phi[i]==i)
for(int j=i;j<=maxn;j+=i) phi[j]=phi[j]/i*(i-1);
}
void PreWork()
{
for(int i=1;i<=maxn;i++)
for(int j=2;j<=maxn/i;j++) f[i*j]+=phi[j]*i;
for(int i=1;i<=maxn;i++) f[i]+=f[i-1];
}
int main()
{
Si();
PreWork();
int t;
scanf("%d",&t);
while(t--) scanf("%d",&n),printf("%lld\n",f[n]);
return 0;
} 预处理,
询问。
查看6道真题和解析
