Star (欧拉函数)

题面

Fernando won a compass for his birthday, and now his favorite hobby is drawing stars: first, he marks N points on a circumference, dividing it into N equal arcs; then, he connects each point to the k-th next point, until returning to the first point.

Depending on the value of k, Fernando may or may not reach all points marked on the circumference; when that happens, the star is called complete. For example, when N = 8, the possible stars are shown in the figure below. Stars (a) and (c) are complete, while stars (b) and (d) are not.

Stars for N=8 and k in {1-4}

 

Depending on the value of N, it may be possible to draw many different stars; Fernando asked you to write a program that, given N, determines the number of complete stars he can draw.

Input

The input contains several test cases. Each test case contains a single line, containing a single integer N (3 ≤ N < 2^31), indicating the number of arcs in which the circumference was divided.

Output

For each test case, your program must print a single line containing a single integer, indicating the number of complete stars that can be drawn.

题解

考虑这个圆上的一个点为起点

如果选择一个距离 K 使之可以被遍历完,那么一定有一个时候,它可以跳到与A相邻的B点,这是肯定的吧

反过来说,如果对于某个K,跳的次数为X,如果 XK mod N = 1,那么K一定是一种合法方案,

这是不是就意味着,X是K关于N的逆元?

我们知道,K有关于N的逆元的条件是K与N互质,

那么答案就为 φ(N) / 2

为什么要除以二呢,因为 K = p 和 K = N - p画出来的图长得一样,

CODE

(笔者vjudge暂时被封)

(以下是Alzh的代码)

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

typedef long long LL;

LL Euler(LL n)
{
    LL res=n;
    for(LL i=2; i*i<=n; ++i)
    {
        if(n%i==0)
        {
            res=res/i*(i-1);
            while(n%i==0)
                n/=i;
        }
    }
    if(n>1)
        res=res/n*(n-1);
    return res;
}

int main()
{
    LL n;
    while(~scanf("%lld",&n))
        printf("%lld\n",Euler(n)/2);
    return 0;
}

 

posted @ 2019-11-23 10:46  DD_XYX  阅读(270)  评论(0编辑  收藏  举报