对于质数 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)
一种求解模奇质数意义下的二次同余方程的算法。
即 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
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;
}