题解 P4296 【[AHOI2007]密码箱】
由题意有
\(x^2\equiv 1\;mod\;n\)
对题目的公式进行变形
\(x^2-1=k\times n\)
\((x+1)(x-1)=k\times n\)
由唯一分解定理,我们构造\(a,b,\)使
\(a|(x+1),b|(x-1)\)
或
\(a|(x-1),b|(x+1)\)
然后我们枚举\(a,b,\)找出所有满足条件的\(x\)
我们可以保证所有的\(x\)都被枚举。刘汝佳:有兴趣的读者可以自行查阅相关资料
\(p.s.:\) 枚举时的小技巧,令\(a\le b\),则枚举\(a\),枚举所有满足条件的\(kb+1\;or\;kb-1,\;a\)只用枚举到\(\sqrt n\)
记得开\(long\;long\)请忽略我的#define int long long
\(Code\)
#pragma GCC optimize(2)
#include <cstdio>
#include <iostream>
#include <set>
#include <cmath>
#define int long long
using namespace std;
set<int> st;//set去重
signed main()
{
int n,sn,b;
cin>>n;
sn=sqrt(n);
if(n==1)
{
puts("None");
return 0;
}
st.insert(1);
for(int i=1;i<=sn;i++)
{
if(n%i==0)
{
b=n/i;
for(int j=b+1;j<=n;j+=b)
if((j+1)%i==0) st.insert(j);
for(int j=b-1;j<=n;j+=b)
if((j-1)%i==0) st.insert(j);
}
}
if(!st.size()) puts("None");
for(set<int>::iterator it=st.begin();it!=st.end();it++)
printf("%d\n",*it);
return 0;
}