转载自:http://hi.baidu.com/fhhgoeqlilqrtxr/item/296f2319e11365ff9c778ac5
/* hdu3930 broot 离散k次根 ,离散对数
http://acm.hdu.edu.cn/showproblem.php?pid=3930
类试题: http://acm.hdu.edu.cn/showproblem.php?pid=3223
k, m , newx ,(0 <= newx , m ,k <= 1.5*10^15) , m is a prime number.
求出x^k mod m = newx 其中所有 x 的值
预备1. 原根定义 .若 g^phi(m)=1,mod m,当t<phi(m),g^t!=1,mod m,则称g
是 模m的原根,phi是欧拉函数.
性质1.若 gcd(g,m)=1,则 g^ phi(m)=1,mod m.
例1. m=17,phi(m)=16; 2^8=1,mod m.2不是 模m的原根
3^k!=1, k<16, 3是 模m的原根
性质2.若 g是 模m的原根,m素数,则
{1,2,...,m-1} = {g,g^2,...,g^(m-1)}
即对 任意 i in [1,m-1], 存在j,使 i=g^j, mod m
例2. m=17,3是 模m的原根
{g,g^2,...,g^(m-1)}={3,9,10,13,5,15,11,16,14,8,7,4,12,2,6,1}
一般地,素数 m 的最小原根 g,2<=g<=100
原根计算.设p1,...,pk是m-1的素因子
step 1. g=2
step 2. 若g^((m-1)/pi )!=1,mod m,i=1,2,..,k
则 g是原根。结束
否则 g++,转 step 2。
预备2. 离散对数定义.若 a^t=b,mod m,则称t是以a为底的b的对数,mod m
b!=0,mod m.
可记为 t=loga(a,b,m);
若果 loga(a,b,m)不存在,记为loga(a,b,m)=-1;
例3. loga(2,3,17)=-1,即 不存在t使 2^t=3,mod 17
性质3. 设g是 模m的原根,则对任意b!=0,mod m,loga(g,b,m)存在
题目要求我们求出x^k mod m = newx 其中所有 x 的值。因为其中规定了 m
总是素数,所以我们可以很容易的找到一个m的原根g,然后利用
babystep求出 t1使 g^t1 mod m = newx,然后我们能利用同余原理轻易得出若
t2=m-1,g^(t1+n*t2) mod m = newx ,因为 g^(n*t2)=1 mod m
简单地说 ,如果 t1 %k=0, m0=t1/k,t1=m0*k则
g^t1=g^ (m0*k)= (g^m0)^k=newx,mod m
x=g^m0 是 x^k mod m = newx的解
一般地说 如果 m0*k = t1, mod t2 // ax=b ,mod m
则 g^(m0*k)=g^t1 =newx ,mod m
x=g^m0是一个解
m0*k = t1, mod t2 (1) ,这是把 m0看做未知数的方程
(1)有解的 条件是 t1% d=0, d=gcd(k,t2)
m0*k/d = t1/d, mod t2/d (2) ,和(1)等价的方程
m0=inv(k/d) * t1/d
设 t1%d=0
计算方法:用扩展Euclid算法 :
ex_gcd( k, t2, d, x0, y0 );
x0*k+y0*t2=d
x0*k/d+y0*t2/d=1
inv(k/d)=x0 ,mod t2/d
m0 = x0*t1/d,mod t2/d;
其他 解mi是
mi=m0+i*(t2/d),i=1,2,...,d-1
求出g^m0,g^m1......g^m(d-1)
一系列数字就是我们要求的答案了。
算法
1. 计算 m的一个原根 g
2. 计算 t1=loga(g,newx,m),即要求 t1使 g^t1=newx,mod m
根据性质3. t1是存在的,t1 in[1,m-1],计算量是 O(m) ,
babystep是一种计算量是 O(m^0.5)的方法
z = ceil( m^0.5);
则 [1,m-1]中的数可表示为 t1=i*z+j, j<z
g^t1=g^(i*z+j) = g^(i*z) * g^j
先计算出 e[j]= g^j,mod m.
如果 有j<z, e[j]= g^j=newx,mod m,则 t1=j,结束
否则 如果 有j<z,
e[j]= g^j=newx*inv(g^z),mod m,即
g^z * g^j =newx,mod m 则 t1=z+j,结束
............................
否则 如果 有j<z,
e[j]= g^j=newx*inv(g^(i*z)),mod m,即
g^(i*z) * g^j =newx,mod m 则 t1=i*z+j,结束
3. 算出 t1后, g^t1=newx,mod m ,设想 g^((t1*x0)*k) =newx,mod m
x0 =inv(k),则 x= g^(t1*x0),x^k=newx,mod m
ex_gcd( k, t2, d, x0, y0 );
if(t1%d!=0) 无解,否则
m0 = x0*t1/d,mod t2/d;
其他 解mi是
mi=m0+i*(t2/d),i=0,1,2,...,d-1
x={g^mi,i=0,i<d}
*/