数论基础(POJ2407)

来源:互联网 发布:英制螺丝孔算法 编辑:程序博客网 时间:2024/06/17 21:58
Relatives
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 14350 Accepted: 7175

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

7120

Sample Output

6

4

这个题拿到后,第一反应是开循环,用镶嵌循环写,但是看到数据的大小1,000,000,000。太大了,因为我们知道,一般计

算机的运算速度大约在10^7-10^8次/s之间开镶嵌循环肯定超时,所以就去discuss里面看了看,有很多大佬说这题要用欧拉公

式,于是我就去网上找了几篇关于欧拉的博客。下面引用一段:

要计算一个正整数n的欧拉函数的方法如下:1. 将n表示成素数的乘积: n = p1 ^ k1 * p2 ^ k2 * ... * pn ^ kn(这里p1, p2, ..., pn是素数)2. PHI(n) = (p1 ^ k1 - p1 ^ (k1 - 1)) * (p2 ^ k2 - p2 ^ (k2 - 1)) * ... *(pn ^ kn - pn ^ (kn - 1))              = Mult { pi ^ ki - pi ^ (ki -1) }

看了许久方才弄明白这个公式,借鉴了一些别人博客里面的欧拉函数,尝试性的写了以下代码

#include <stdio.h>int main(){    long long n;    while(scanf("%lld",&n)!=EOF&&n)    {        long long t=n;        for(int i=2;i*i<=n;i++)        {            if(n%i==0)            {                t=t/i*(i-1);        //相当于一个递推公式其函数原型没变                while(n%i==0)                    n/=i;           //除去这个数中含有的所有的该因子            }        }        if(n>1) t=t/n*(n-1);        //处理特殊情况的数        printf("%d\n",t);    }    return 0;}

一次AC。但还是得好好理解,这题以后还会来看。

0 0
原创粉丝点击