[Ybt Gold Medal Navigation 8-4-1] Number of Integers / Euler Function Examples

Number of integers

Topic link: ybt gold medal navigation 8-4-1

General idea

Give you a number n, find the number that meets the following conditions: it
must be less than n, or a divisor of n, and it cannot be relatively prime to n.

Ideas

When you see coprime, you naturally think of Euler's function.

But it is not mutually prime, and it is annoying to say that it is not a round number.

That’s simple, let’s tolerate it and use all (according to less than nnn hasn − 1 n-1n1 ) minus isnndivisor of n orwithnnThe number of n is relatively prime.

When calculating the approximate number, you will put nnn is also counted as a divisor, but your previous condition is less thannnn , then continue to tolerate and exclude, here is a subtraction, then you have to add back1 11

Then when you calculate the round number and calculate the prime, it will both count to 1 11 , that is also tolerated, add back1 11

In this way, you can directly reduce the number of numbers and the number of co-primes and then exclude them based on the above.

Next is how to find the number of coprime, that is, how to calculate Euler's function.

Here is a single method.
φ (i) = i × p 1 − 1 p 1 ×... × pm − 1 pm \varphi(i)=i\times\dfrac{p_1-1}{p_1}\times...\times\dfrac {p_m-1}{p_m}φ ( i )=i×p1p11×...×pmpm1
p i p_i pi Is its prime factor)

The principle is probably that it cannot appear any factors, and the factors are composed of prime factors.
Then it is similar to tolerance, you have a certain prime number pi p_ipiBunch 1 ~ i 1 \ sim i1i is divided into many lengthspi p_ipiThe interval, and then each interval has a position that cannot be selected (that is, that position is pi p_ipiMultiples of).
Then every prime factor is like this, this is the formula.

Code

#include<cstdio>
#define ll long long

using namespace std;

ll n, ans;

ll phi(ll x) {
    
    //求n的phi值
	int re = x;
	for (int i = 2; i * i <= x; i++)
		if (n % i == 0) {
    
    
			re = re / i * (i - 1);
			while (n % i == 0) n /= i;
		}
	if (n >> 1)
		re = re / n * (n - 1);
	return re;
}

int main() {
    
    
	scanf("%d", &n);
	ans = n - 1;//满足小于 n 的有 n-1 个
	
	for (ll i = 1; i * i <= n; i++)//求 n 因子的个数
		if (n % i == 0) {
    
    
			ans -= 2;
			if (i * i == n) ans++;
		}
	ans++;//前面求的时候把 n 也算个进去,减多了,要加回去
	
	ans -= phi(n);//求与 n 互质的数的个数(n 的 phi 值)
	
	ans++;//求因子和求互质的地方都算了 1,重复了要加回去。
	
	printf("%lld\n", ans);
	
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/114124969