比赛:2021-08-12:D

题目大意

给定n,求出所有正整数x,满足小于n,且x^2(%n)=1
将满足的x按从小到大的顺序依次换行输出

题目分析

\(x^2=kn+1\)
\(x^2+x-x-1=kn\)
\((x+1)(x-1)=kn\)
我们可以分别拆解\(k,n\)为两个相乘的形式\(k=k_1*k_2,n=n_1*n_2\)
所以可得
\(k_1*k_2=k,n_1*n_2=n\)
\(k_1*n_1=(x+1)\)
\(k_2*n_2=(x-1)\)
直接枚举\(n_1\)
\(y=n_1\)
则有\(n_2=n/y\)④,$ k_1y=(x+1)\( 因为\)x<n\(,所以 \)(x+1)<=n\( 将\)k_1y=(x+1)\(代入其中得 \)k_1*y<=n\( 同除\)y\(得 \)k_1<=n/y\( 所以可以枚举\)k_1$
范围在\(0 \leq k_1 \leq n/y\)
\(d\)为枚举的\(k_1\)
则有\((x+1)=d*y\)
\(x=d*y-1\)
把④⑤代入②得
\(( d*y-2 )=k_2*(n/y)\)
如果\((d*y-2)\)\((n/y)\)的整倍数,则\(k_2\)有整数解,所以\(x=d*y-1\)即为一组合法情况。

反过来同理,也可以设\(y=n_2,d=k_2\),同样可以推出\((d*y+2)=k_1*(n/y)\)
如果\((d*y+2)\)\((n/y)\)的整数倍,那么\(x=d*y+1\)也为一种合法情况。

因为\(d*y\)有可能大于\(n\),所以要判断\(x\)是否小于\(n\),小于才输出

\(Code\)

#include<algorithm>
#include<iostream>
#include<cstdio>
#include<cmath>
#define ll long long
#define sco 100
using namespace std;
ll n,x,y,l,r,ans[sco];
int main(){
	register ll tot=0;
	scanf("%lld",&n);
	if(n==1){printf("None");return 0;}
	int siz=sqrt(n);
	for(register ll i=1;i<=siz;++i){
		y=n/i;
		if(n%i==0){
			for(register int d=0;d<=i;++d){
				if((d*y-2)%i==0)ans[++tot]=d*y-1;
				if((d*y+2)%i==0)ans[++tot]=d*y+1;
			}
		}
	}
	sort(ans+1,ans+1+tot);
	l=1,r=unique(ans+1,ans+1+tot)-ans-1;
	for(register ll i=l;i<=r;++i)if(ans[i]>0 && ans[i]<n)printf("%lld\n",ans[i]);
	return 0;
}
posted @ 2021-08-18 22:00  ssl_lhj  阅读(41)  评论(0)    收藏  举报