UVA 10820 Send a Table (欧拉函数)
输入n,对于整数x,y(1<=x,y<=n),f(x,y)=f(kx,ky),k式正整数。
所以可以用过f(x,y)的性质对函数表进行化简。问在[1,n]内最简的整数表有多少个元素。
问题的实质是求在[1,n]内有多少对互素的整数,因为如果x,y不互质,那必然存在因子k,满足f(x’,y’)=f(kx’,ky’)。
对于欧拉函数F,F(x)的值就表示小于n且与n互素的数的个数。
欧拉函数F的表达式可以由相容排斥原理得到,且可以化为下面的形式:
对于x有质因子分解式:x=p1a1p2a2…pkak
有F(x)=n(1-1/p1)(1-1/p2)…(1-1/pk)
求[1,n]的欧拉函数i表不必对F(1)…F(n)一一求值。可以用Eratosthenes筛法,用[1,n]内的素数pi累乘去求F(k*pi)的值,时间复杂度为O(nloglogn)。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int max_n=5e4+5;
int n;
long long f[max_n];
void solve(void)
{
memset(f,0,sizeof(f));
for(int i=2;i<max_n;i++)if(!f[i])
for(int j=i;j<max_n;j+=i)
{
if(!f[j])f[j]=j;
f[j]=f[j]/i*(i-1);
}
for(int i=3;i<max_n;i++)
// cout<<f[i]<<endl;
f[i]+=f[i-1];
}
int main(void)
{
// freopen("out.txt","w",stdout);
solve();
while(~scanf("%d",&n)&&n)
{
printf("%lld\n",f[n]*2+1);
}
// fclose(stdout);
}