JZOJ 1460. 无题noname【数学】


题意:

给定一个 n n n,求出所有 1 1 1 n n n之间的 x x x,使得 x 2 = 1   ( m o d   n ) x^2=1\ (mod\ n) x2=1 (mod n)


分析:

很妙的思维
先把原式变为 ( x + 1 ) ∗ ( x − 1 ) = k ∗ n ( k   ϵ   Z ) (x+1)*(x-1)=k*n(k\ \epsilon\ \mathbb{Z}) (x+1)(x1)=kn(k ϵ Z)
假设 a ∗ b = n a*b=n ab=n a ∣ x + 1 , b ∣ x − 1 a|x+1,b|x-1 ax+1bx1,当然 a , b a,b ab的位置是可以互换的
如果可以满足这样的条件, x = k ∗ b + 1 x=k*b+1 x=kb+1必定是合法的
所以我们可以枚举 a a a,这样可以算出 b b b,再通过枚举 k k k,算出 x x x
然后将 x x x代入 x + 1 x+1 x+1中看是否能被 a a a整除


代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
inline LL read()
{
    
    
	LL s=0,f=1; char c=getchar();
	while(c<'0'||c>'9') {
    
    if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9') {
    
    s=s*10+c-'0';c=getchar();}
	return s*f;
}
LL ans[2000005],len=0;
int main()
{
    
    
	LL n=read();ans[++len]=1;
	for(LL i=1;i*i<=n;i++)
	{
    
    
		if(n%i) continue;
		LL a=i,b=n/i;
		for(LL j=1;j*b+1<=n;j++) if(!((j*b+2)%a)) ans[++len]=j*b+1;
		for(LL j=1;j*b-1<=n;j++) if(!((j*b-2)%a)) ans[++len]=j*b-1;
	}
	sort(ans+1,ans+1+len);
	len=unique(ans+1,ans+1+len)-ans-1;
	for(LL i=1;i<=len;i++) printf("%lld\n",ans[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/109098239
今日推荐