[POJ 2407]Relatives(欧拉函数)

Description

Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if there are no integers x > 1, y > 0, z > 0 such that a = xy and b = xz.

Input

There are several test cases. For each test case, standard input contains a line with n <= 1,000,000,000. A line containing 0 follows the last case.

Output

For each test case there should be single line of output answering the question posed above.

Sample Input

7
12
0

Sample Output

6
4

Source

Waterloo local 2002.07.01

刚开始我傻X了,本着蒟蒻的思维,照着欧拉函数的公式写了如下的代码,先筛素数然后分解质因数最后再算公式

//欧拉函数h(n)=n*(1-1/p1)*(1-1/p2)*'''''*(1-1/pk);
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

#define MAXN 1010

using namespace std;

bool isPrime[MAXN];
int Prime[MAXN],PriNum[MAXN],cnt=0,tot=0;

void GetPrime()
{
    cnt=0;
    for(int i=1;i<MAXN;i++) isPrime[i]=true;
    for(int i=2;i<MAXN;i++)
    {
        if(isPrime[i])
        {
            Prime[++cnt]=i;
            for(int j=2*i;j<MAXN;j+=i)
                isPrime[j]=false;
        }
    }
}

void DecQualityFactor(int n) //分解质因数
{
    tot=0;
    for(int i=1;Prime[i]*Prime[i]<=n;i++)
    {
        if(n%Prime[i]==0)
        {
            PriNum[++tot]=Prime[i];
            while(!(n%Prime[i])) n/=Prime[i];
        }
    }
    if(n!=1) PriNum[++tot]=n;
}

int h(int n)
{
    double ans=n;
    for(int i=1;i<=tot;i++)
    {
        ans*=(1.0-1.0/(double)PriNum[i]);
    }
    return (int)ans;
}

int main()
{
    GetPrime();
    while(1)
    {
        cnt=0,tot=0;
        memset(PriNum,0,sizeof(PriNum));
        int N;
        cin>>N;
        if(!N) break;
        DecQualityFactor(N);
        cout<<h(N)<<endl;
    }
    return 0;
}

好吧这个代码根本没办法过,因为题目给的n的范围太大了,数组完爆内存,也就是说这题根本就不能用数组保存什么质因数和素数的。

下面才是真正的AC代码,又短又快神神哒

//欧拉函数h(n)=n*(1-1/p1)*(1-1/p2)*'''''*(1-1/pk);
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

#define MAXN 1000

using namespace std;

int h(int n)
{
    int ans=n;
    for(int i=2;i<=n;i++)
    {
        if(n%i==0)
        {
            ans=ans/i*(i-1);
            n/=i;
            while(n%i==0) n/=i;
        }
    }
    return ans;
}
int main()
{
    while(1)
    {
        int N;
        cin>>N;
        if(!N) break;
        cout<<h(N)<<endl;
    }
    return 0;
}



[POJ 2407]Relatives(欧拉函数),布布扣,bubuko.com

时间: 2024-10-07 21:51:14

[POJ 2407]Relatives(欧拉函数)的相关文章

POJ 2407 Relatives 欧拉函数题解

最基本的欧拉函数: 欧拉函数:求小于n的与n互质的个数 欧兰函数公式:φ(x)=x(1-1/p1)(1-1/p2)(1-1/p3)(1-1/p4)-..(1-1/pn),其中p1, p2--pn为x的所有质因数 就是要求这样的式子啦,不过求这条式子,相信有很多种方法可以求,这个不是难题: 不过问题是如何巧妙地求,如何简洁地写出代码. 直接硬求,或者求出质因数之后求都不是巧妙的方法了,参考了下别人的代码才知道可以写的这么巧妙的. 下面程序可以说是连消带打地求式子结果,分解质因子,可以如此简明地把解

poj 2154 Color 欧拉函数优化的ploya计数

枚举位移肯定超时,对于一个位移i,我们需要的是它的循环个数,也就是gcd(i,n),gcd(i,n)个数肯定不会很多,因为等价于n的约数的个数. 所以我们枚举n的约数,对于一个约数k,也就是循环个数为n/k这样的个数有phi[k]种,证明网上有很多.所以答案就是 phi[k]*(pow(n,n/k)) (k是n的所有约数) 由于约数会很大所以不能打表,只能单个算. 再由于最后要除以n,如果做除法就不能直接取模,所以我们在算每一次pow(n,n/k)的时候,都少乘一个n,这样就相当于除法了. #i

POJ 2480 (约数+欧拉函数)

题目链接: http://poj.org/problem?id=2480 题目大意:求Σgcd(i,n). 解题思路: 如果i与n互质,gcd(i,n)=1,且总和=欧拉函数phi(n). 如果i与n不互质,那么只要枚举n的全部约数,对于一个约数d,必有gcd(i/d,n/d)互质,这部分的gcd和=d*欧拉函数phi(n/d). 不断累加暴力求解即可. 其实还可以公式化简,不过实在太繁琐了.可以参考金海峰神的解释. 由于要求好多欧拉函数,每次都分解质因数法必然TLE,这里所以采用O(√n)求单

POJ 1284-Primitive Roots(欧拉函数求原根)

Primitive Roots Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1284 Appoint description:  System Crawler  (2015-04-06) Description We say that integer x, 0 < x < p, is a primitive root mod

poj 3478 poj 3090(欧拉函数的应用)

3478题目意思是Farey序列是由一系列不能约分的分数a/b(0<a<b<=n且gcd(a,b)=1)按照递增的顺序组成的,然后给出了Fn的前几项,让你计算Fn中有多少个分数. 很明显Fn中的数的个数就是分别与(2,3,4.....n-1,n)互质的数的个数的和.也就是求欧拉函数的前n项和. 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <st

poj 2773 利用欧拉函数求互质数

题意:找到与n互质的第 k个数 开始一看n是1e6 敲了个暴力结果tle了,后来发现k达到了 1e8 所以需要用到欧拉函数. 我们设小于n的 ,与n互质的数为  (a1,a2,a3.......a(phi(n))) 那么显然,在区间  [ k*n , (k+1)*n ]内的互质数即为 k*n+(a1,a2,a3.......a(phi(n))) 所以只需要求出 (a1,a2,a3.......a(phi(n))) 就可以利用欧拉函数快速找到后面的数 代码如下: #include <iostrea

Period of an Infinite Binary Expansion POJ - 3358(欧拉函数)

Period of an Infinite Binary Expansion POJ - 3358 题意:给一个分数,让求其二进制形式的最小循环节ans2和循环节开始的位置ans1. 以下内容转自http://blog.csdn.net/u013508213/article/details/42496543 小数二进制的转换方法就是不断*2,mod 分母. 比如:1/10  2/10  4/10  8/10  16/10  32/10... 模后:1/10  2/10  4/10  8/10  

POJ 2773-Happy 2006(欧拉函数)

Happy 2006 Time Limit:3000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 2773 Appoint description:  System Crawler  (2015-04-06) Description Two positive integers are said to be relatively prime to each other

数论 - 欧拉函数模板题 --- poj 2407 : Relatives

Relatives Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11372   Accepted: 5544 Description Given n, a positive integer, how many positive integers less than n are relatively prime to n? Two integers a and b are relatively prime if ther