How to Efficiently Compute Euler's Totient Function for Large Ranges?

  • Context: MHB 
  • Thread starter Thread starter Saitama
  • Start date Start date
  • Tags Tags
    Euler Function
Click For Summary
SUMMARY

The discussion focuses on efficiently computing Euler's Totient Function, φ(n), for large ranges defined by two integers a and b, where 0 < a < b < 10^14 and b - a < 10^5. The provided C++ code implements a method to calculate φ(n) using a combination of trial division and optimizations based on the properties of even and odd integers. However, the initial approach results in Time Limit Exceeded (TLE) errors, prompting suggestions to utilize advanced factorization algorithms like Pollard's Rho to improve performance.

PREREQUISITES
  • Understanding of Euler's Totient Function and its mathematical properties
  • Familiarity with C++ programming and basic algorithms
  • Knowledge of number theory concepts such as coprimality
  • Experience with optimization techniques in computational problems
NEXT STEPS
  • Research advanced factorization algorithms, specifically Pollard's Rho
  • Learn about the Sieve of Eratosthenes and its applications in number theory
  • Explore dynamic programming techniques for optimizing range queries
  • Study the mathematical properties of φ(n) for various integer types
USEFUL FOR

Mathematicians, competitive programmers, and software developers interested in number theory and optimization techniques for large-scale computations.

Saitama
Messages
4,244
Reaction score
93
Following is the problem I am trying to solve: SPOJ.com - Problem ETFS

In number theory, the totient phi(n) of a positive integer n is defined to be the number of positive integers less than or equal to n that are coprime to n.

Input

The lonely line in input contains two integers a, b.

Output

Print phi(n) for n from a to b (inclusive).

Example

Input:
1 5

Output:
1
1
2
2
4

Constraints

0 < a < b < 10^14
b - a < 10^5

Here is my code:

Code:
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

typedef long long ll;

ll solve(ll n)
{
	ll i, ans=n;
	for(i=2; i*i<=n; ++i)
	{
		if(n%i==0)
			ans-=ans/i;
		while(n%i==0)
			n/=i;
	}
	if(n>1)
		ans-=ans/n;
	return ans;
}

int main() {
	ll T, n, a, b, i;
	scanf("%lld %lld", &a, &b);
	vector<ll> x(b-a+1, -1);
	for(n=a; n<=b; ++n)
	{
		if(x[n-a]==-1)
		{
			x[n-a]=solve(n);
			if(2*n<=b)
			{
				if(n%2) x[2*n-a]=x[n-a];
				else x[2*n-a]=2*x[n-a];
			}
			for(i=n*4; i<=b; i*=2)
			{
				x[i-a]=2*x[i/2-a];
			}
		}
	}
	for(i=0; i<b-a+1; ++i)
		printf("%lld\n", x[i]);
	return 0;
}

Some explanation of what I am trying to do.

The naive approach i.e finding $\phi (n)$ of every number in the given range using the $O(\sqrt{n})$ won't work. So whenever I have found $\phi(n)$, I use the following relation: $\phi(2n)=2\phi(n)$ if $n$ is even and $\phi(2n)=\phi(n)$ is $n$ is odd. With this, I don't have to run the solve() function ($O(\sqrt{n}$) for every integer in the range but even with this optimisation, I get TLE. :(

Please help. Thanks!
 
Technology news on Phys.org
Hi Pranav,

Perhaps we can use that
\begin{cases}\phi(p)&=p-1\\\phi(p^n)&=(p-1)p^{n-1}\\\phi(a\cdot p^n)&=\phi(a)\cdot\phi(p^n) &\text{ if }p\nmid a\end{cases}
Then we might apply a sieve or dynamic programming.
 
Hint: trial division is not the only factorization algorithm that exists. There are many more advanced algorithms, some of which are easy to implement and will pretty much instantly factor your input integers up to 10^14. For instance, Pollard's Rho is pretty simple to implement, and in practice runs in worst case $O(\sqrt[4]{n})$.

Then you can use I Like Serena's suggestions to take advantage of the fact that you have to factor a range of consecutive integers, etc...
 

Similar threads

  • · Replies 1 ·
Replies
1
Views
2K
Replies
4
Views
2K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
Replies
9
Views
3K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 5 ·
Replies
5
Views
3K
  • · Replies 17 ·
Replies
17
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 6 ·
Replies
6
Views
2K