欧拉准则
对于质数 p p p, x 2 ≡ a ( m o d p ) ⇔ a p − 1 2 ≡ 1 ( m o d p ) x^2\equiv a\pmod p\Leftrightarrow a^{\frac{p-1}{2}}\equiv 1\pmod p x2≡a(modp)⇔a2p−1≡1(modp)。
证明:
充分性:
a
p
−
1
2
=
(
x
2
)
p
−
1
2
=
x
p
−
1
≡
1
(
m
o
d
p
)
a^{\frac{p-1}{2}}=(x^2)^{\frac{p-1}{2}}=x^{p-1}\equiv 1\pmod p
a2p−1=(x2)2p−1=xp−1≡1(modp)
必要性:
设
g
g
g为模
p
p
p意义下的原根,
g
i
≡
a
(
m
o
d
p
)
g^i\equiv a\pmod p
gi≡a(modp),则
g
i
(
p
−
1
)
2
≡
1
(
m
o
d
p
)
g^{\frac{i(p-1)}{2}}\equiv 1\pmod p
g2i(p−1)≡1(modp)
g
g
g为原根,则
(
p
−
1
)
∣
i
(
p
−
1
)
2
(p-1)|\frac{i(p-1)}{2}
(p−1)∣2i(p−1),
i
i
i为偶数,
x
≡
g
i
2
(
m
o
d
p
)
x\equiv g^{\frac i2}\pmod p
x≡g2i(modp)
Cipolla算法
一种求解模奇质数意义下的二次同余方程的算法。
即 p p p为奇质数,给定 a a a,求 x x x满足: x 2 ≡ a ( m o d p ) x^2\equiv a\pmod p x2≡a(modp)
复杂度 O ( log p ) O(\log p) O(logp)
具体算法:
可能需要死记硬背一下。。。
随机找到任意一个 b b b,满足 b 2 − a ≡ w b^2-a\equiv w b2−a≡w, w w w是模 p p p意义下的非二次剩余( w p − 1 2 ≡ − 1 ( m o d p ) w^{\frac{p-1}{2} }\equiv -1\pmod p w2p−1≡−1(modp))。
类似于虚数,设
i
=
w
i= \sqrt w
i=w,扩域后每个数表达为
(
a
,
b
)
=
a
+
b
i
(a,b)=a+bi
(a,b)=a+bi,运算为:
(
r
1
,
d
1
)
+
(
r
2
,
d
2
)
=
(
r
1
+
r
2
,
d
1
+
d
2
)
(r_1,d_1)+(r_2,d_2)=(r_1+r_2,d_1+d_2)
(r1,d1)+(r2,d2)=(r1+r2,d1+d2)
(
r
1
,
d
1
)
⋅
(
r
2
,
d
2
)
=
(
r
1
r
2
+
d
1
d
2
w
,
r
1
d
2
+
r
2
d
1
)
(r_1,d_1)·(r_2,d_2)=(r_1 r_2+d_1d_2w,r_1d_2+r_2d_1)
(r1,d1)⋅(r2,d2)=(r1r2+d1d2w,r1d2+r2d1)
< G , + , ⋅ > <G,+,·> <G,+,⋅>是个环,满足交换律和结合律。
答案即为: x = ( b + i ) p + 1 2 x=(b+i)^{\frac {p+1}{2}} x=(b+i)2p+1
证明:
x
2
\quad x^2
x2
=
(
b
+
i
)
p
(
b
+
i
)
=(b+i)^p(b+i)
=(b+i)p(b+i)
=
(
b
p
+
i
p
)
(
b
+
i
)
=(b^p+i^p)(b+i)
=(bp+ip)(b+i) (
(
b
+
i
)
p
(b+i)^p
(b+i)p二项式定理展开后其余项均含
p
p
p模后为0)
由
b
p
≡
b
,
i
p
=
w
p
−
1
2
i
=
−
i
b^p\equiv b,i^p=w^{\frac{p-1}{2}}i=-i
bp≡b,ip=w2p−1i=−i
则
x
2
=
(
b
−
i
)
(
b
+
i
)
=
b
2
−
i
2
=
b
2
−
w
=
a
x^2=(b-i)(b+i)=b^2-i^2=b^2-w=a
x2=(b−i)(b+i)=b2−i2=b2−w=a
例题
传送门:bzoj5104
求在
(
m
o
d
1
0
9
+
9
)
\pmod{10^9+9}
(mod109+9)的意义下,数字
N
N
N在
F
i
b
Fib
Fib数列中出现在哪个位置
无解输出
−
1
-1
−1
N
<
=
1
0
9
+
9
N < = 10^9+9
N<=109+9
题解
F i b Fib Fib数列的通项公式: F n = ( 1 + 5 2 ) n − ( 1 − 5 2 ) n 5 F_n=\frac{(\frac{1+\sqrt 5}{2})^n-(\frac{1-\sqrt 5}{2})^n}{\sqrt 5} Fn=5(21+5)n−(21−5)n
吐槽一下这怎么记得到啊。。。
设 t = ( 1 + 5 2 ) n , T = 5 N t=(\frac{1+\sqrt 5}{2})^n,T=\sqrt 5N t=(21+5)n,T=5N
则 t − ( − 1 ) n 1 t = T t-(-1)^n\frac{1}{t}=T t−(−1)nt1=T
左右同乘 T T T:
得到方程 t 2 − T t − ( − 1 ) n = 0 t^{2}-Tt-(-1)^n=0 t2−Tt−(−1)n=0
分 n n n的奇偶讨论,先求出 Δ \sqrt\Delta Δ后 B S G S BSGS BSGS求解。
代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+9,qrt5=383008016,nv2=500000005,blk=sqrt(mod)+1,bs=691504013;
int n,ans,ca,cb;
map<int,int>mp[2];
inline int fp(int x,int y)
{
int re=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1) re=(ll)re*x%mod;
return re;
}
inline int ad(int x,int y){x+=y;return x>=mod?x-mod:x;}
inline int dc(int x,int y){x-=y;return x<0?x+mod:x;}
namespace sc_surplus{
int w,a,b;
struct cc{
int r,i;
cc(int r,int i):r(r),i(i){};
cc operator *(const cc&ky)const
{return cc(ad((ll)r*ky.r%mod,(ll)i*ky.i%mod*(ll)w%mod),ad((ll)r*ky.i%mod,(ll)i*ky.r%mod));}
cc operator *=(const cc&ky){return (*this)=(*this)*ky;}
};
inline int fp(cc x,int y)
{
cc re=cc(1,0);
for(;y;y>>=1,x*=x) if(y&1) re*=x;
return re.r;
}
inline bool ck(int x)
{return (::fp((w=dc((ll)x*x%mod,a)),(mod-1)/2)==mod-1);}
inline int fd_sqrt(int x)
{
if(::fp(x,(mod-1)/2)!=1) return 0;
a=x;for(b=rand();!ck(b);b=rand());
return fp(cc(b,1),(mod+1)/2);
}
}
inline void cal(int od)
{
int i,j,a=ca,b=cb,pw;
for(i=0;i<2;++i) if(!mp[i].empty()) mp[i].clear();
for(i=0;i<blk;++i){
j=i&1;
if(mp[j].find(a)==mp[j].end()) mp[j][a]=i;
if(mp[j].find(b)==mp[j].end()) mp[j][b]=i;
a=(ll)a*bs%mod;b=(ll)b*bs%mod;
}
pw=fp(bs,blk);int vl=pw,re=blk;
for(i=0;i<=blk;++i){
j=-1;
if(od){
if((re&1)&&(mp[0].find(vl)!=mp[0].end())) j=mp[0][vl];
else if((!(re&1))&&(mp[1].find(vl)!=mp[1].end())) j=mp[1][vl];
}else{
if((re&1)&&(mp[1].find(vl)!=mp[1].end())) j=mp[1][vl];
else if((!(re&1))&&(mp[0].find(vl)!=mp[0].end())) j=mp[0][vl];
}if(~j) {re-=j;ans=min(ans,re);return;}
vl=(ll)vl*pw%mod;re+=blk;
}
}
int main(){
srand(time(0));
scanf("%d",&n);ans=mod+10;
if(n==1) {puts("1");return 0;}
int i,j,x,y;
n=(ll)n*qrt5%mod;
if((x=sc_surplus::fd_sqrt(((ll)n*n+4)%mod))){
ca=(ll)ad(n,x)*nv2%mod;cb=(ll)dc(n,x)*nv2%mod;cal(0);
}
if((x=sc_surplus::fd_sqrt(((ll)n*n-4+mod)%mod))){
ca=(ll)ad(n,x)*nv2%mod;cb=(ll)dc(n,x)*nv2%mod;cal(1);
}
printf("%d",ans==mod+10?(-1):ans);
return 0;
}