Алгоритъм 1:
За всяко i<N, ако НОД(N,i)=1, то i е едно от търсените числа.
Сложността на този алгоритъм е приблизително O(N*logN).


Алгоритъм 2:
Count_Oiler(N) използва теоремата на Ойлер, която гласи:
Ако означим с ф(N) броя на числата по-малки от N и взаимно прости с N,
то
ф(N) = N*(1-1/p1)*(1-1/p2)*(1-1/p3)*...*(1-1/pk),
където N = p1^a1*p2^a2*...*pk^ak и p1,p2,..,pk-прости числа,
p1<p2<...<pk
т.е. това е каоничният вид на N.

За намиране простите делители на N, използваме, че дадено число N може
да има само един прост делител по-голям от sqrt(N)(корен квадратен от
N). Така че, за да намерим различните прости делители на дадено N, делим
го последователно на простите му делители от 2 до sqrt(N). Ако след
това, N е различно от 1, то това е единственият прост делител на N
по-голям от sqrt(N)

Така сложността на алгоритъма е О(sqrt(N))


#include <stdio.h>
#include <math.h>
#include <time.h>


int Count_Oiler(long N) {
int P;
int Cnt;
long long C1, C2;
int N1 = N;
if(N==1) return 0;


P = 2;

C1 = 1;
C2 = 1;
int SqrtN = (int)sqrt(N)+1;
while(N!=1) {
if(N%P==0)
{
C1 *= (P-1);
C2 *= P;
while(N%P==0) N/=P;
}
P++;
if(P>SqrtN) break;
}
if(N!=1) { C1*=(N-1); C2*=N; }
Cnt = (N1*C1)/C2;
return Cnt;

}

int main(void) {
int N;
scanf("%ld",&N);
printf("%ld\n",Count_Oiler(N));
return 0;
}