欧拉准则:设p为奇素数,则
a p − 1 2 ≡ ( a p ) ( m o d p ) a^{\frac{p-1}{2}}\equiv (\frac{a}{p})(mod\ p) a2p−1≡(pa)(mod p)
其中 a p \frac{a}{p} pa为勒让德符号
证明:假设a为二次剩余,如 a ≡ b 2 ( m o d p ) a\equiv b^2(mod\ p) a≡b2(mod p),由费马小定理可知
a ( p − 1 ) / 2 ≡ ( b 2 ) ( p − 1 ) / 2 ≡ 1 ( m o d p ) a^{(p-1)/2}\equiv (b^2)^{(p-1)/2}\equiv 1(mod\ p) a(p−1)/2≡(b2)(p−1)/2≡1(mod p)
∵ ( a p ) = 1 \because (\frac{a}{p})=1 ∵(pa)=1所以上式也可以写作 a ( p − 1 ) / 2 ≡ ( a p ) ( m o d p ) a^{(p-1)/2}\equiv (\frac{a}{p})(mod\ p) a(p−1)/2≡(pa)(mod p)由此当p为二次剩余时,欧拉准则成立
在证明二次非剩余也满足欧拉准则前,我们需要先观察上式子,据上面的式子,我们可以发现每个二次剩余都是同余方程 x ( p − 1 ) / 2 − 1 ≡ ( m o d p ) x^{(p-1)/2}-1\equiv(mod\ p) x(p−1)/2−1≡(mod p)的解,而之前已经证过模p多项式根定理,这个方程至多有 p − 1 2 \frac{p-1}{2} 2p−1个解,而p有 p − 1 2 \frac{p-1}{2} 2p−1这样我们就会发现,凡二次剩余均满足上式,且满足上式的均是二次剩余.有了这个结论之后我们再对非二次剩余满足欧拉准则进行证明.
假设a为二次非剩余,由费马小定理,有 a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv1(mod\ p) ap−1≡1(mod p),所以
0 ≡ a p − 1 − 1 ≡ ( a ( p − 1 ) / 2 − 1 ) ( a ( p − 1 ) / 2 + 1 ) ( m o d p ) 0\equiv a^{p-1}-1\equiv(a^{(p-1)/2}-1)(a^{(p-1)/2}+1)(mod\ p) 0≡ap−1−1≡(a(p−1)/2−1)(a(p−1)/2+1)(mod p)
由于a为二次非剩余,因此 p ̸ ∣ ( a ( p − 1 ) / 2 − 1 ) p\not \mid(a^{(p-1)/2}-1) p̸∣(a(p−1)/2−1)故 a ( p − 1 ) / 2 ≡ − 1 ( m o d p ) a^{(p-1)/2}\equiv -1(mod\ p) a(p−1)/2≡−1(mod p)由于a为二次非剩余时 ( a q ) = − 1 (\frac{a}{q})=-1 (qa)=−1因此 a ( p − 1 ) / 2 ≡ ( a q ) ( m o d p ) a^{(p-1)/2}\equiv(\frac{a}{q})(mod\ p) a(p−1)/2≡(qa)(mod p)再a为二次非剩余时也成立
在介绍Cipolla算法之前我们需要先引入一些定理与引理
算法的用处是解 x 2 ≡ n ( m o d p ) x^2\equiv n(mod\ p) x2≡n(mod p)因此下面所称的方程均是左式
下面的引理或者定理中,所有的p均为奇素数
引理: n ( p − 1 ) / 2 ≡ ± 1 ( m o d p ) n^{(p-1)/2}\equiv ±1 (mod\ p) n(p−1)/2≡±1(mod p)
证明:即欧拉准则,一个数或为二次剩余数,或为二次非剩余数.
引理:方程 x 2 ≡ n ( m o d p ) x^2\equiv n(mod\ p) x2≡n(mod p)有解当且仅当 n ( p − 1 ) / 2 ≡ 1 ( m o d p ) n^{(p-1)/2}\equiv 1(mod\ p) n(p−1)/2≡1(mod p)
证明:方程有解则n为二次剩余
定理:设a满足 ω = a 2 − n \omega=a^2-n ω=a2−n不是模p的二次剩余,即 x 2 ≡ ω ( m o d p ) x^2\equiv \omega(mod\ p) x2≡ω(mod p)无解,则 x ≡ ( a + ω ) p + 1 2 x\equiv (a+\sqrt\omega)^{\frac{p+1}{2}} x≡(a+ω)2p+1是方程的解
证明:首先处理 ( a + ω ) p ≡ a p + C p 1 ω a p − 1 + . . . C p p − 1 ω p − 1 a + ω p ( m o d p ) (a+\sqrt\omega)^p\equiv a^p+C_p^1\sqrt\omega a^{p-1}+...C_p^{p-1}\sqrt\omega ^{p-1}a+\sqrt\omega^p(mod\ p) (a+ω)p≡ap+Cp1ωap−1+...Cpp−1ωp−1a+ωp(mod p)由于 p ∣ C n i p\mid C_n^i p∣Cni故原式可以转化为 ( a + ω ) p ≡ a p + ω p − 1 2 ω (a+\sqrt\omega)^p\equiv a^p+\omega^{\frac{p-1}{2}}\sqrt\omega (a+ω)p≡ap+ω2p−1ω由 ω \omega ω为二次非剩余可知 ω p − 1 2 ≡ − 1 ( m o d p ) \omega^{\frac{p-1}{2}}\equiv -1(mod\ p) ω2p−1≡−1(mod p),和费马小定理 a p ≡ a ( m o d p ) a^p\equiv a(mod\ p) ap≡a(mod p)可知原式可以化为 ( a + ω ) p ≡ a + ω ( m o d p ) (a+\sqrt\omega)^p\equiv a+\sqrt\omega(mod\ p) (a+ω)p≡a+ω(mod p)故有
x 2 = ( a + ω ) p + 1 ≡ ( a + ω ) ⋅ ( a − ω ) x^2= (a+\sqrt\omega)^{p+1}\equiv (a+\sqrt\omega)\cdot(a-\sqrt\omega) x2=(a+ω)p+1≡(a+ω)⋅(a−ω)
≡ a 2 − ω \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \equiv a^2-\omega ≡a2−ω
≡ n ( m o d p ) \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \equiv n(mod\ p) ≡n(mod p)
得证.
例题http://acm.timus.ru/problem.aspx?space=1&num=1132
Cipolla算法裸题
#include
#include
using namespace std;
typedef long long LL;
struct pii{
int x,y;
pii(int x=0,int y=0):x(x),y(y){}
};
LL w;
pii multi(pii a,pii b,LL p)
{
return pii((a.x*b.x%p+a.y*b.y%p*w%p)%p,(a.x*b.y%p+a.y*b.x%p)%p);
}
LL quick_pow_D(pii a,LL b,LL p)
{
pii ans(1,0);
while(b)
{
if(b&1) ans=multi(ans,a,p),b--;
a=multi(a,a,p);
b>>=1;
}
return ans.x;
}
LL quick_pow(LL a,LL b,LL p)
{
LL ans=1;a%=p;
while(b)
{
if(b&1) ans=ans*a%p;
a=a*a%p;
b>>=1;
}
return ans;
}
int check(LL n,LL p)
{
return quick_pow(n,(p-1)/2,p);
}
LL mod(LL a,LL n)
{
a%=n;
if(a<0) return a+n;
return a;
}
void solve(int b,int p)
{
LL a,t;
while(1)
{
a=rand()%p;
t=a*a-b;
w=mod(t,p);
if(check(w,p)==p-1) break;
}
pii temp(a,1);
int ans=quick_pow_D(temp,(p+1)/2,p);
int ans2=p-ans;
if(ans>ans2) swap(ans,ans2);
printf("%d %d\n",ans,ans2);
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int a,n;
scanf("%d%d",&a,&n);a%=n;
if(n!=2&&check(a,n)==n-1) printf("No root\n");
else if(n==2)
{
if(a==1) printf("1\n");
else printf("No root\n");
}
else
{
solve(a,n);
}
}
}