给定一个N,求出所有1到N之间的x,使得x^2=1(mod N)。
将这个式子变形(x-1)(x+1)=0(MOD P) ,那么就可以枚举P的每一对因数(a,b),我们把方程化为ax*by=P*T(T为任意常数)
那么这里ax,by必须满足ax-by=2,这个可以用扩展gcd求解
求出x,y后,我们将所有形如a*(x*(2/gcd)+k*(b/r))的解加入vector并排序输出(注意正负,对这一步不理解的可以看这里:同余方程,这里相当于是解ax=2(mod b)的所有解)
#include<stdio.h>
#include<math.h>
#include<vector>
#include<algorithm>
#define L long long
using namespace std;
vector<L> ans;
L n,sq;
inline L D(L x){ return (x+n)%n; }
L extgcd(L a,L b,L& x,L& y){
if(b){
L r=extgcd(b,a%b,y,x);
y-=x*(a/b); return r;
} else { x=1; y=0; return a; }
}
void adj(L a,L b){
L x,y,r=extgcd(a,b,x,y);
if(r>2) return;
x*=2/r; y*=2/r;
while(abs(x*a)<n) x-=b/r; x+=b/r;
while(abs(x*a)<n) {
ans.push_back(x>0?1ll*x*a-1:-x*1ll*a+1);
x+=b/r;
}
}
int main(){
scanf("%d",&n);
for(L i=1;1ll*i*i<=n+3;++i) if(n%i==0) adj(i,n/i);
sort(ans.begin(),ans.end());
printf("%d\n",ans[0]);
for(L i=1,z=ans.size();i<z;++i)
if(ans[i]!=ans[i-1]) printf("%lld\n",ans[i]);
}