还是欧拉函数,写的有点特殊。。。
在去A一次, 用正常人得做法。。。。。
//正常人不要学习我的方法。。。。。
//看看取乐的了。。。。
#include <stdio.h>
#include <math.h>
#include <string.h>
__int64 prime[10000], visit[10000], len;
//筛素数
__int64 Prime()
{
__int64 i, j;
len = 0;
memset(visit, 0, sizeof(visit));
for (i = 2; i <= 10000; i++)
{
if (visit[i] == 0)
{
for (j = 2 * i; j <= 10000; j += i)
visit[j] = 1;
prime[len++] = i;
}
}
}
int main()
{
__int64 i, n, cnt, temp, p_factor[10000], phi;
Prime();
while (scanf("%I64d", &n) && n)
{
temp = n;
//剔除质因素并保留在数组p_factor中
for (i = cnt = 0; i < len; i++)
{
if (temp == 0 || temp == 1) break;
if (temp % prime[i] == 0)
{
p_factor[cnt++] = prime[i];
while (temp && temp % prime[i] == 0) { temp /= prime[i]; }
}
}
//没有被10000以内的素数整除一定是素数
if (cnt == 0)
printf("0\n");
else
{
//素因子可能大于10000
//就这儿纠结了好久
if (temp != 1)
p_factor[cnt++] = temp;
phi = n;
for (i = 0; i < cnt; i++)
{
phi = phi / p_factor[i] * (p_factor[i] - 1);
//printf("%d ", p_factor[i]);
}
//printf("\nPHI = %d cnt = %d\t", temp, cnt);
printf("%I64d\n", n - phi - 1);
}
}
return 0;
}
A掉了。。。
#include <stdio.h>
__int64 Euler(int n)
{
__int64 i, ans = n;
for (i = 2; i < 10000; i++)
if (n % i == 0)
{
ans = ans / i * (i-1);
while (n % i == 0) { n /= i; }
if (n == 1) break;
}
if (n > 10000)
ans = ans / n * (n-1);
return ans;
}
int main()
{
__int64 n;
while (scanf("%I64d", &n))
{
if (n == 0) break;
printf("%I64d\n", n - Euler(n) - 1);
}
return 0;
}