给定方程 X^A = B (mol C)  ,求 在[0,C) 中所有的解 , 并且C为质数。

设 rt 为 C 的原根 , 则 X = rt^x  (这里相当于求 A^x =B (mol C) 用大步小步算法即可)

那么 ( rt^x ) ^ A = b (mol C)

   rt^Ax = b (mol C)

由费马小定理, 设 Ax = (C-1)*y +t1   ---------------- ( * )

可得  rt^t1 =b ( mod C)

这里运用大步小步算法可以计算出 t1 。

得到 t1 后反代会 (*)式 , 利用扩展欧几里得求出符合条件的x解。

由于此方程相当于解 Ax mod (C-1) = t1 , 共用 gcd ( a , C-1 ) 组解。

最后用快速幂计算出所有的X解即可。

 const maxn=;
maxh=;
var a,b,c,rt,t1,t2,x,y,d:int64;
i:longint;
ans,pm,pri:array[..maxn*] of int64;
pd:array[..maxn*] of boolean;
cnt,nm:longint;
h:array[..maxh,..] of int64;
procedure init;
var i,j:longint;
begin
fillchar(pd,sizeof(pd),false);
i:=; nm:=;
while i<=maxn do
begin
inc(nm);
pm[nm]:=i;
j:=i;
while j<=maxn do
begin
pd[j]:=true;
j:=j+i;
end;
while pd[i] do inc(i);
end;
end;
function pow(x,y,p:int64):int64;
var sum:int64;
begin
x:=x mod p;
sum:=;
while y> do
begin
if y and = then sum:=sum*x mod p;
x:=x*x mod p;
y:=y >> ;
end;
exit(sum);
end;
procedure divide(n:int64);
var i:longint;
begin
cnt:=;
i:=;
while pm[i]*pm[i]<=n do
begin
if n mod pm[i]= then
begin
inc(cnt);
pri[cnt]:=pm[i];
while n mod pm[i]= do n:=n div pm[i];
end;
inc(i);
end;
if n> then
begin
inc(cnt);
pri[cnt]:=n;
end;
end;
function findrt(p:int64):int64;
var g,t:int64;
flag:boolean;
begin
divide(p-);
g:=;
while true do
begin
flag:=true;
for i:= to cnt do
begin
t:=(p-) div pri[i];
if pow(g,t,p)= then
begin
flag:=false;
break;
end;
end;
if flag then exit(g);
inc(g);
end;
end;
procedure insert(x,y:int64); inline;
var hash:int64;
begin
hash:=x mod maxh;
while (h[hash,]<>x) and (h[hash,]<>) do hash:=(hash+) mod maxh;
h[hash,]:=x;
h[hash,]:=y;
end;
function find(x:int64):int64; inline;
var hash:int64;
begin
hash:=x mod maxh;
while (h[hash,]<>x) and (h[hash,]<>) do hash:=(hash+) mod maxh;
if h[hash,]= then exit(-) else exit(h[hash,]);
end;
function work(a,b,p:int64):int64;
var j,m,x,cnt,ans,t:int64;
i:longint;
begin
ans:=;
m:=trunc(sqrt(p))+;
x:=pow(a,m,p);
j:=;
for i:= to m do
begin
j:=j*x mod p;
if find(j)=- then insert(j,i);
end;
j:=;
for i:= to m- do
begin
t:=find(j*b mod p);
if t<>- then
begin
cnt:=m*t-i;
if cnt<ans then ans:=cnt;
end;
j:=j*a mod p;
end;
exit(ans);
end;
function gcd(x,y:int64):int64;
begin
if y= then exit(x) else exit(gcd(y,x mod y));
end;
procedure exgcd(a,b:int64;var x,y:int64);
var t:int64;
begin
if b= then
begin
x:=;
y:=;
exit;
end;
exgcd(b,a mod b,x,y);
t:=x;
x:=y;
y:=t-a div b*y;
end;
procedure swap(var a,b:int64); inline;
var c:longint;
begin
c:=a; a:=b; b:=c;
end;
procedure sort(l,r:int64);
var i,j,x:int64;
begin
i:=l; j:=r; x:=ans[(l+r) div ];
while i<=j do
begin
while ans[i]<x do inc(i);
while x<ans[j] do dec(j);
if i<=j then
begin
swap(ans[i],ans[j]);
inc(i); dec(j);
end;
end;
if l<j then sort(l,j);
if i<r then sort(i,r);
end;
begin
init;
readln(b,a,c);
rt:=findrt(c);
t1:=work(rt,b,c);
t2:=c-;
d:=gcd(a,t2);
if t1 mod d<> then
begin
writeln();
exit;
end;
exgcd(a,t2,x,y);
t1:=t1 div d;
t2:=t2 div d;
ans[]:=((x*t1 mod t2)+ t2) mod t2;
for i:= to d do ans[i]:=ans[i-]+t2;
for i:= to d do ans[i]:=pow(rt,ans[i],c);
sort(,d);
writeln(d);
for i:= to d- do write(ans[i],' ');
writeln(ans[d]);
end.

HDU3930 (原根)的更多相关文章

  1. HDU3930(离散对数与原根)

    题目:Broot 题意:给出k,m,newx的值,求方程x^k(mod m)=newx的解,其中m为素数. 解法步骤: (1)先暴力求m的原根g (2)大步小步求g^t1(mod m)=newx (3 ...

  2. 51nod1135(求最小原根)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1135 题意:中文题诶- 思路:设m是正整数,a是整数,若a模 ...

  3. [POJ1284]Primitive Roots(原根性质的应用)

    题目:http://poj.org/problem?id=1284 题意:就是求一个奇素数有多少个原根 分析: 使得方程a^x=1(mod m)成立的最小正整数x是φ(m),则称a是m的一个原根 然后 ...

  4. 51nod 1135 原根

    题目链接:51nod 1135 原根 设 m 是正整数,a是整数,若a模m的阶等于φ(m),则称 a 为 模m的一个原根.(其中φ(m)表示m的欧拉函数) 阶:gcd(a,m)=1,使得成立的最小的 ...

  5. hdu4992 Primitive Roots(所有原根)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4992 题意:给出n,输出n的所有原根. 思路:求出n的一个原根x,那么对于所以的i,i<phi( ...

  6. HDU5478 原根求解

    看别人做的很简单我也不知道是怎么写出来的 自己拿到这道题的想法就是模为素数,那必然有原根r ,将a看做r^a , b看做r^b那么只要求出幂a,b就能得到所求值a,b 自己慢慢化简就会发现可以抵消n然 ...

  7. 【poj1284-Primitive Roots】欧拉函数-奇素数的原根个数

    http://poj.org/problem?id=1284 题意:给定一个奇素数p,求p的原根个数. 原根: { (xi mod p) | 1 <= i <= p-1 } is equa ...

  8. 【BZOJ 1319】 Sgu261Discrete Rootsv (原根+BSGS+EXGCD)

    1319: Sgu261Discrete Roots Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 389  Solved: 172 Descriptio ...

  9. 【HDU 4992】 Primitive Roots (原根)

    Primitive Roots   Description We say that integer x, 0 < x < n, is a primitive root modulo n i ...

随机推荐

  1. think in java 读书笔记 2 —— 套接字

    目录 think in java 读书笔记 1 ——移位 think in java 读书笔记 2 —— 套接字 think in java 读书笔记 3 —— 数据报 概要 1. 套接字基本知识 2 ...

  2. 读流testDemo

    import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.I ...

  3. 用c#开发苹果应用程序 xamarin.ios方式

    NetworkComms网络通信框架序言 Networkcomms网络通信框架来自于英国,支持以xamarin.ios的方式开发苹果应用程序 其开源版本2.3.1中带有一个示例程序,实现聊天功能,只要 ...

  4. 【模板下载】innosetup 制作.net安装包的模板

    NetworkComms网络通信框架序言 这个模板是在博客园和CodeProject上的代码修改而成的,感谢原作者 模板是2个 innosetup 制作.net 2.0 安装包的模板 innosetu ...

  5. SqlServer2008快照隔离模式的业务应用

    场景: 有200个检测点,每个检测点每天采集5个数据,对表的读写都是随机的(即有可能同时读写),总共有5年的数据. 存储方案A: 日期 点号 类型 值 20120101 001 A 1.0 20120 ...

  6. C++定义构造函数必须使用初始化列表的场合

    明其理,而知其然也. 先给理论.1. 初始化 != 赋值. a.初始化代表为变量分配内存. 变量在其定义处被编译器初始化(编译时). 在函数中, 函数参数初始化发生在函数调用时(运行时). b.赋值代 ...

  7. 【个人使用.Net类库】(1)INI配置文件操作类

    开发接口程序时,对于接口程序配置的IP地址.端口等都需要是可配置的,而在Win Api原生实现了INI文件的读写操作,因此只需要调用Win Api中的方法即可操作INI配置文件,关键代码就是如何调用W ...

  8. HDU 1358 简单kmp

    题目大意: 找到所有的可组成连续字符串相连的位置,和循环字符串的个数 #include <cstdio> #include <cstring> #include <alg ...

  9. 黑客界大拿tombkeeper文章:怎么学好技术成为技术大拿(题目我自拟的)

    这两天论坛上又有人开始抱怨世风日下,大家都现实了,都不开放了,不交流了.对这种“月经贴”,我基本上已经习惯了,不过因为吃了粉皮炖鸡,心情比较好,于是就说了两句. 三四年前,当时我对人性的看法还不像现在 ...

  10. oracle触发器的小例子

    实现功能: 插入数据前触发,检查与插入数据几个属性相同的在表中的列将状态改为false,再执行插入. 解决方案: CREATE OR REPLACE TRIGGER tri_insert BEFORE ...