数论 Count QBXT Test Ⅰ T1

版权声明:未经本蒟蒻同意,请勿转载本蒻博客 https://blog.csdn.net/wddwjlss/article/details/83342435

题意:问有几个无序二元组 ( x , y ) (x, y) 满足 x y 1 xy ≡ 1 ( m o d    P ) (mod \ \ P ) 0 x < P ; 0 y < P 0 ≤ x < P; 0 ≤ y <P 。无序二元组是指,如果 P = 10 P = 10 ( 3 , 7 ) (3,7) ( 7 , 3 ) (7,3) 只算一次。

首先我们将式子化成方程形式: x y k P = 1 xy-kP=1 ,其中 P P 为已知常数,我们将 x x 也看做一个常数,我们发现解的情况就是 g c d ( P , x ) = 1 gcd(P,x)=1 ,也就是小于 P P 并且与 P P 互质的数的个数,即 ϕ ( P ) \phi(P) 。如果 x y 1 ( m o d    P ) xy ≡ 1 (mod \ \ P) ,那么 ( x , y ) ( y , x ) (x,y) 和 (y,x) 一定会各出现一次,也就是被多算了一次,而这个东西的值即为 ϕ ( P ) \phi(P) ,但是其中 x = y x=y 的情况只有一次。设满足 x 2 1 ( m o d    P ) x^2 ≡ 1 (mod \ \ P) x x n u m num 个,答案即为 n u m + ϕ ( P ) 2 \frac{num+\phi(P)}{2} 。注意当 P = 1 P=1 时答案为 1 1 ,因为 0 0 = 1   m o d   1 0*0=1\ mod\ 1 ϕ ( n ) = p i c i 1 ( p i 1 ) \phi(n) = \prod {p_i}^{c_{i}-1}(p_i-1)

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int p,ans,num;
int phi(int n)
{ 
    int ans=n,a=n;
    for(int i=2;i*i<=a;i++)
	{
        if(a%i==0)
		{
       		ans=ans/i*(i-1);
            while(a%i==0) 
		 		a/=i;	
        }
    }
    if(a>1) 
		ans=ans/a*(a-1);
    return ans;
}
int main()
{
	cin>>p;
	for(int i=1;i<p;++i)
		if((1ll*i*i)%p==1)
			num++;
	if(p==1)
	{
		cout<<"1";
		return 0;
	}	
	cout<<(phi(p)+num)/2;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/wddwjlss/article/details/83342435