题目:
https://ac.nowcoder.com/acm/problem/19877
给定一个
n
n
n,求出所有
x
x
x,满足
x
2
≡
1
(
m
o
d
n
)
n
≤
2
∗
1
0
9
x^2\equiv 1(mod\quad n)\quad n\le2*10^9
x2≡1(modn)n≤2∗109
思路:
x
2
≡
1
(
m
o
d
n
)
(
x
+
1
)
(
x
−
1
)
≡
0
(
m
o
d
n
)
\begin{aligned} x^2&\equiv 1(mod\quad n)\\ (x+1)(x-1)&\equiv 0(mod\quad n)\\ \end{aligned}
x2(x+1)(x−1)≡1(modn)≡0(modn)
则存在
y
y
y,使得
(
x
−
1
)
(
x
+
1
)
=
n
y
(x-1)(x+1)=ny
(x−1)(x+1)=ny
令
y
=
y
1
×
y
2
,
n
=
n
1
×
n
2
y=y_1\times y_2,n=n_1\times n_2
y=y1×y2,n=n1×n2,因此
y
1
×
n
1
×
y
2
×
n
2
=
(
x
−
1
)
(
x
+
1
)
y_1\times n_1\times y_2\times n_2=(x-1)(x+1)
y1×n1×y2×n2=(x−1)(x+1),所以我们可以得到
y
1
×
n
1
=
(
x
−
1
)
,
y
2
×
n
2
=
(
x
+
1
)
y_1\times n_1=(x-1),y_2\times n_2=(x+1)
y1×n1=(x−1),y2×n2=(x+1)(因为
x
−
1
x-1
x−1一部分来自
n
n
n,一部分来自
y
y
y,同理
x
+
1
x+1
x+1)
所以我们可以直接在
n
\sqrt{n}
n的时间内枚举
n
1
,
n
2
n_1,n_2
n1,n2,然后暴力枚举
y
2
y_2
y2,判断
y
1
y_1
y1是否存在
/*program from Wolfycz*/
#include<set>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
int x=0,f=1; char ch=gc();
for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline int read(){
int x=0,f=1; char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<3)+(x<<1)+ch-'0';
return x*f;
}
inline void print(int x){
if (x<0) putchar('-'),x=-x;
if (x>9) print(x/10);
putchar(x%10+'0');
}
int n;
set<int>st;
void work(int a,int b){
for (int i=1;1ll*i*b<=n;i++){//上界无所谓,反正答案取模
if ((i*b+2)%a==0) st.insert((i*b+1)%n);
if ((i*b-2)%a==0) st.insert((i*b-1)%n);
}
}
int main(){
n=read();
for (int i=1;i*i<=n;i++){
if (n%i) continue;
work(i,n/i);
}
for (set<int>::iterator it=st.begin();it!=st.end();it++) printf("%d\n",*it);
}