找新朋友
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 58 Accepted Submission(s) : 30
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
新年快到了,“猪头帮协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友?请你编程序帮会长计算出来。
Input
第一行是测试数据的组数CN(Case number,1<CN<10000),接着有CN行正整数N(1<n<32768),表示会员人数。
Output
对于每一个N,输出一行新朋友的人数,这样共有CN行输出。
Sample Input
2
25608
24027
Sample Output
7680
16016
Author
SmallBeer(CML)
Source
杭电ACM集训队训练赛(VII)
欧拉函数:对正整数n,欧拉函数是少于或等于n的数中与n互质的数的数目。
int eular_phi(int n)
{
int m=(int)sqrt(n+0.5); //避免浮点误差
int ans=n;
for(int i=2;i<=m;i++)
{
if(n%i==0) //i是n的质因数
{
ans=ans/i*(i-1); //欧拉函数定义eular(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pk),pi是n的质因数,先除法避免中间数据溢出
}
while(n%i==0) //任意一个数都能写成质数的乘积形式
n/=i;
}
if(n>1) //n不为1说明剩下的n也是一个质数
ans=ans/n*(n-1);
return ans;
{
int m=(int)sqrt(n+0.5); //避免浮点误差
int ans=n;
for(int i=2;i<=m;i++)
{
if(n%i==0) //i是n的质因数
{
ans=ans/i*(i-1); //欧拉函数定义eular(n)=n*(1-1/p1)*(1-1/p2)*...*(1-1/pk),pi是n的质因数,先除法避免中间数据溢出
}
while(n%i==0) //任意一个数都能写成质数的乘积形式
n/=i;
}
if(n>1) //n不为1说明剩下的n也是一个质数
ans=ans/n*(n-1);
return ans;
}
类似筛选法打表
int phi[maxn];
void phi_table()
{
phi[1]=1;
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 phi_table()
{
phi[1]=1;
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);
}
}
}
当n接近1e9时,打表会超内存。