比赛: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;
}

浙公网安备 33010602011771号