正题
题目链接:https://www.luogu.com.cn/problem/P4296
题目大意
一个数字nnn,求有多少个x<nx<nx<n使得x2%n=1x^2\%n=1x2%n=1。
解题思路
x2=kn+1x^2=kn+1x2=kn+1
x2−1=knx^2-1=knx2−1=kn
(x−1)(x+1)%n=0(x-1)(x+1)\%n=0(x−1)(x+1)%n=0
⇒\Rightarrow⇒
x(x+2)%n=0(x+2<=n)x(x+2)\%n=0(x+2<=n)x(x+2)%n=0(x+2<=n)
对于这个式子,我们若有ab=n(b>a)ab=n(b>a)ab=n(b>a),a∣xa|xa∣x且b∣yb|yb∣y的话那么就有xy%n=0xy\%n=0xy%n=0
所以我们可以先求出每一个≥n\geq \sqrt{n}≥n的nnn的约数zzz,然后这个约数是aaa还是bbb都行,然后暴力枚举z∣xz|xz∣x的即可。
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,p[100000],ans[200000],m,cnt;
int main()
{scanf("%d",&n);for(int i=1;i*i<=n;i++)if(!(n%i)) p[++m]=n/i;for(int i=1;i<=m;i++){int x=p[i];for(int j=x;j<=n;j+=x){if(!((j-2)%(n/x))) ans[++cnt]=j-1;if(!((j+2)%(n/x))) ans[++cnt]=j+1;}} sort(ans+1,ans+1+cnt);printf("1\n");for(int i=1;i<=cnt;i++)if(ans[i]!=ans[i-1]&&ans[i]<n)printf("%d\n",ans[i]);
}