2021-08-12 SSL 模拟赛 T4
没有标题的第
n
>
=
(
1
0
9
m
o
d
10
)
n>=(10^9 \bmod 10)
n>=(109mod10) 天
原题:【洛谷 P4296 [AHOI2007] 密码箱】
题目大意:
求 1~n-1 中所有存在 i 2 m o d n = 0 i^2\bmod n=0 i2modn=0 的 i。
思路:
我们把式子转化一下形式,得到:
(
i
+
1
)
(
i
−
1
)
m
o
d
n
=
0
(i+1)(i-1) \bmod n=0
(i+1)(i−1)modn=0
即为
(
i
+
1
)
(
i
−
1
)
=
k
∗
n
(i+1)(i-1)=k*n
(i+1)(i−1)=k∗n
所以i+1,i-1必然都包含 n 的一个或以上的约数
那么我们枚举 n 的约数,再去枚举 k 判断即可。
注意枚举 n 的约数要从
n
\sqrt n
n 之后枚举,这样你的 k 在枚举时就会减少时间,不会
T
L
E
TLE
TLE
大佬的题解:
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
ll n,v,ans[10001],top;
void find(ll x)
{
rep(i,0,n/x)
{
ll now=i*x+2;
if(now%(n/x)==0) ans[++top]=i*x+1;
now=i*x-2;
if(now%(n/x)==0) ans[++top]=i*x-1;
}
}
int main()
{
scanf("%lld",&n);
if(n==1)
{
printf("None");
return 0;
}
v=sqrt(n);
rep(i,1,v)
if(n%i==0)
find(n/i);
sort(ans+1,ans+1+top);
rep(i,1,top)
if(ans[i]>0&&ans[i]<n)
if(ans[i]!=ans[i-1])
printf("%lld\n",ans[i]);
return 0;
}