求同余方程x^A=B(mod m)的解个数(原根与指标)
2019-04-13 22:10发布
生成海报
分类: 数论2013-08-05
16:11 132人阅读 收藏 举报
求方程:
的解个数
分析:设
,那么上述方程解的个数就与同余方程组:
的解等价。
设同于方程的解分别是:
,那么原方程的解的个数就是
所以现在的关键问题是求方程:
的解个数。
这个方程我们需要分3类讨论:
第一种情况:
对于这种情况,如果方程的某个解设为
,那么一定有
,可以得到
,即
所以方程的解个数就是:
,也就是
第二种情况:
这样也就是说p|B,设
,
,本方程有解的充要条件是A|t,
那么我们设t=kA,
所以进一步有:
,因为
,这样又转化为第三种情况了。
第三种情况:
那么我们要求指标;求指标的话又要求原根。并且奇素数p的原根也是p^a的原根,所以说求个p的原根就好了。
且如果有解,则解的个数为(A,φ(p^a))。
求指标的话就是要解决A^x ≡ B (mod p^a)的问题。由于本情况保证了(p^a, B)=1,用个Baby-step-Giant-step就
能解决问题。
方程x^A ≡ B (mod p^a)有解,当且仅当(A,φ(p^a))|ind B。ind B表示B对于p^a的任一原根的指标。
如果不知道原根与指标的现在就补一下吧:
原根部分:
定义一:设m>1,(a,m)=1,则使得
成立的最小正整数r,称为a对模m的指数,或者a对模m的阶,记为
定理一:若m>1,(a,m)=1,
,则
定义二:若
,则a是模m的原根。
定理二:如果大于1的正整数m有原根,那么它一共有
个不同的原根。
定理三:模m有原根的必要条件是m=2,4,p^a或者2p^a,其中p是奇素数。
定理四:设m>1,
所有不同的奇因数是
,(g,m)=1,则g是模m的原根的充要条件是:
1<=i<=k
指标,n次剩余部分:
现在我们来研究同余式
(a,m)=1,有解的条件以及解数,注意现在的m=p^a或者2p^a,
,g是模m的一个原根。
若(n,c)=d ,(a,m)=1,则上述同余式有解的充要条件是d|inda,并且在有解的条件下,解数为d。
在模m的一个简化剩余系中,n次剩余的个数是
定理一:若r通过模c的最小非负完全剩余系,则g^r通过模m的一个简化剩余系。
证明:g是模m的一个原根,则
对模m两两不同余,又因为(g,m)=1,所以(g^r,m)=1
因此
是模m的一个简化剩余系。
定理一:设a是一整数,(a,m)=1,若对模m的一个原根g,有一整数r存在使得下式

成立,则r就叫做以g为底的a对模m的一个指标,记为r=inda。
经典题目:HDU3731
分类: 数论2013-02-12
20:04 125人阅读 收藏 举报
扩展Baby Step Giant Step深入学习请戳这里
题目:Clever Y
求解A^x = B (mod C) 中 0 <= x < C 的解。
本算法的安全性更高。
[cpp] view
plaincopy
-
#include
-
#include
-
#include
-
#include
-
-
#define CC(m ,what) memset(m , what , sizeof(m))
-
-
typedef long long LL ;
-
-
LL A, B ,C ;
-
-
const int NN=99991 ;
-
-
bool hash[NN];
-
int idx[NN];
-
int val[NN];
-
-
void insert(int id , LL vv)
-
{
-
LL v = vv % NN ;
-
while( hash[v] && val[v]!=vv)
-
{
-
v++ ;
-
if(v == NN)
-
v-=NN ;
-
}
-
if(!hash[v])
-
{
-
hash[v] = 1;
-
val[v] = vv ;
-
idx[v] = id ;
-
}
-
}
-
-
int find(LL vv)
-
{
-
LL v = vv % NN ;
-
while( hash[v] && val[v]!=vv)
-
{
-
v++ ;
-
if(v == NN) v-=NN;
-
}
-
if( !hash[v] ) return -1;
-
return idx[v];
-
}
-
void ex_gcd(LL a , LL b , LL& x , LL& y)
-
{
-
if(b == 0)
-
{
-
x = 1 ;
-
y = 0 ;
-
return;
-
}
-
ex_gcd(b ,a%b,x,y);
-
LL t = x;
-
x = y;
-
y=t-a/b*y ;
-
}
-
-
LL gcd(LL a,LL b){
-
while( a%b != 0){
-
LL c = a ;
-
a = b ;
-
b = c % b ;
-
}
-
return b ;
-
}
-
LL baby_step(LL A, LL B , LL C)
-
{
-
LL ans = 1 ;
-
for(LL i=0;i<=50;i++)
-
{
-
if(ans == B) return i ;
-
ans = ans * A % C ;
-
}
-
LL tmp , d = 0 ;
-
LL D = 1 % C ;
-
while( (tmp=gcd(A,C)) != 1 )
-
{
-
if(B % tmp) return -1 ;
-
d++ ;
-
B/=tmp ;
-
C/=tmp ;
-
D = D*A/tmp%C ;
-
}
-
CC( hash , 0) ;
-
CC( idx, -1) ;
-
CC(val , -1) ;
-
LL M = ceil( sqrt(C*1.0) ) ;
-
LL rr = 1 ;
-
for(int i=0;i
-
{
-
insert(i, rr) ;
-
rr = rr * A % C ;
-
}
-
LL x, y ;
-
for(int i=0;i
-
{
-
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮