The Euler function. time-limit-exceeded

The program implements the Euler function (https://ru.wikipedia.org/wiki/Функция_Эйлера), everything seems to work, I checked on tests - there were no errors on sufficiently large numbers, including.

The only problem is that I can't pass the program due to time-limit-exceeded (on the first 9 tests, everything works in 2 milliseconds, and on the 10th test-3.076 seconds). The maximum time limit is 3 seconds. Please help, maybe someone will find where I have in the program it can happen?

#include <iostream>
using namespace std;

int binomialCoeff(int k, int n)  
{ 
    if (k == 0 || k == n)  
        return 1;  
  
    return binomialCoeff(k - 1, n - 1) +  
        binomialCoeff(k, n - 1);  
}

int gsd(int a, int b) {
    while(a!=0 && b!=0) {
        if(a>b) a%=b;
        else b%=a;
    }
    return a+b;
}

int Euler(unsigned long k, unsigned long n) {
    unsigned int result=1; 
    int combination = binomialCoeff(k,n);
    for(int i=2; i<=combination; i++) {
        if(gsd(i,combination) == 1) {
            result++;
        }
    }
    return result;
}

int main() {
    int k, n;
    cin >> k >> n;
    if(k<0 || n<0 || n<k) 
        throw invalid_argument("Binom condition failed");
    cout << Euler(k,n);
    return 0;
}
Author: Mikhailo, 2020-07-02

2 answers

Something is somehow strange you are calculating it... And then, I didn't find any Euler function from two variables on the link. So ask me if I'm answering what you're asking. :)

Recently I had to write it in Python, here is the C/C++translation:

unsigned long long fi(unsigned long long n)
{
    unsigned long long f = n;
    if (n%2 == 0)
    {
        while (n%2 == 0) n /= 2;
        f/= 2;
    }
    for(unsigned long long i = 3; i*i <= n; i += 2)
    {
        if (n%i == 0)
        {
            while (n%i == 0) n /= i;
            f /= i;
            f *= (i-1);
        }
    }
    if (n > 1)
    {
        f /= n;
        f *= (n-1);
    }
    return f;
}

Is this what you need?

On such an unpleasant number as 1879174269099946969 (the square of a prime number, i.e. a complete search), I have about 1.61±0.02 s running on the machine.

 2
Author: Harry, 2020-07-03 19:18:46
int binomialCoeff(int k, int n)
{ 
    if (k == 0 || k == n)  
        return 1;  
  
    return binomialCoeff(k - 1, n - 1) +  
        binomialCoeff(k, n - 1);  
}

This function has exponential complexity. Instead, it is better to count using the formula.

 0
Author: Qwertiy, 2020-07-05 19:10:17