知识点
一 . 引子
题目:UVA11417 GCD
题目描述
给定 n ,求
其中 指的是 i 和 j 的最大公约数。
输入格式
本题有多组数据。
对于每组数据,输出一个整数 n ,如果 n=0 就终止程序。
输出格式
对于每组数据,输出计算结果。
说明 / 范围
对于 100% 的数据,。
输入输出样例
输入 #1
10 100 500 0
输出 #1
67 13015 442011
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
inline int read()
{
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
return x*f;
}
inline int Gcd(int a,int b)
{
if(b==0) return a;
return Gcd(b,a%b);
}
int main()
{
int n;
while(scanf("%d",&n) && n!=0)
{
int ans=0;
for(int i=1;i<=n;++i)
{
for(int j=i+1;j<=n;++j)
{
ans+=Gcd(i,j);
}
}
printf("%d\n",ans);
}
return 0;
}
在这道题中,因为数据范围很小,所以使用通过循环找最大公约数及求和,但是当数据很大的时候就会造成TLE。
相关练习:
(n倍经验系列):
1. UVA11426 拿行李(极限版) GCD - Extreme (II)
5. 洛谷 P2568 GCD
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
const int maxn=1e7+5;
ll int phi[maxn],sum[maxn],f[maxn];
inline ll int read()
{
ll int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
return x*f;
}
inline void phi_table(ll int n)
{
for(int i=2;i<=n;++i) phi[i]=0;
phi[1]=1;
for(int i=2;i<=n;++i)
{
if(!phi[i])
{
for(int j=i;j<=n;j+=i)
{
if(!phi[j]) phi[j]=j;
phi[j]=phi[j]/i*(i-1);
}
}
}
}
int main()
{
ll int n;
while(scanf("%lld",&n) && n!=0)
{
phi_table(n);
for(int i=1;i<=n;++i)
{
for(int j=i*2;j<=n;j+=i)
{
f[n]+=i*phi[j/i];
}
}
sum[2]=f[2];
for(int i=3;i<=n;++i)
{
sum[n]=sum[n-1]+f[n];
}
printf("%lld\n",sum[n]);
}
return 0;
}
8 . 洛谷 P2303 [SDOI2012] Longge 的问题
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define re register
using namespace std;
ll int n;
inline ll int read()
{
ll int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+(c^48);
c=getchar();
}
return x*f;
}
inline void write(ll int x)
{
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
inline ll int euler_phi(ll int n)
{
ll int ans=n;
for(ll int i=2;i*i<=n;++i)
{
if(n%i == 0)
{
ans=ans/i*(i-1);
while(n%i == 0) n/=i;
}
}
if(n!=1) ans=ans/n*(n-1);
return ans;
}
int main()
{
n=read();
ll int ans=0;
for(ll int i=1;i*i<=n;++i)
{
if(n%i == 0)
{
ans+=i*euler_phi(n/i);
if(i*i!=n) ans+=(n/i)*euler_phi(i);
}
}
write(ans);
return 0;
}