给定一个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 ",ans[0]); for(L i=1,z=ans.size();i<z;++i) if(ans[i]!=ans[i-1]) printf("%lld ",ans[i]); }