模素数p的原根g的优美体现在每个模p的非零数以g的幂次出现。所以,对任何数1 <= a < p,我们可选择幂

        g,g^2,g^2,```````,g^(p-2),g^(p-1)

中恰好一个与a模p同余。相应的指数被称为以g为底的a模p的指标。假设p与g已给定,则记指标为I(a)。

以下以2模13的所有幂的形式:

I          1   2  3    4   5   6   7   8    9  10   11 12

2^I(mod 13)   2  4  8  3  6  12  11  9  5  10  7  1

例如,为求I(11),我们搜寻表的第二行直到找到数11,则指标I(11)=7可从第一行得到。

指标法则

  a).  I(ab)=I(a)+I(b) (mod p-1)

  b).  I(a^k)=kI(a) (mod p-1)

g^I(ab)=ab=g^I(a)g^I(b)=g^(I(a)+I(b)) (mod p)

故有g^I(x) = x (mod p-1)

也可以这么理解:g^I(value) = id (mod p-1)

例题:3*x^30=4(mod 37)

I(3*x^30)=I(4)

I(3)+30*I(x)=I(4) (mod 36)

26+30*I(x)=2 (mod 36)

30*I(x)=-24=12 (mod 36)

对于这里I(4)=2解释一下:

其实就是g^2 = 4 (mod 36)

其实这个可以根据g^x =b (mod p)来求

对于本题,g就是37的原根2,b=I(x) p =36

也就是求满足2^x = I(x) (mod 36)的x。用Baby Step Giant Step算法即可哦

提醒:两边不要除以6以得到5*I(x)+2 (mod 36),否则会丢失一些解。

ax = c (mod m)

由扩展欧几里德,知:

I(x)=4,10,16,22,28,34

最后,有指标表(书论书上有哦,自己不放写程序看看),得到x的对应值

I(16)=4,I(25)=10,I(9)=16

I(21)=22,I(12)=28,I(28)=34

其实这里,也可以根据指标的原式公式g^I(x) = x (mod p-1)

故,同余式3*x^30=4 (mod 37)有6个解,即

x=16,25,9,21,12,28 (mod 37)

/** hdu3930.c**  Created on: 2011-10-12*      Author: bjfuwangzhu*/#include<math.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define LL long long
#define nmax 1000010
typedef struct num {int ii;LL value;
} num;
num Num[nmax];
int flag[nmax], prime[nmax], cpfactor[100];
LL pfactor[100];
int plen, len_pfactor;
LL k, n, p, proot, x, y;
void mkprime() {int i, j;memset(flag, -1, sizeof(flag));for (i = 2, plen = 0; i < nmax; i++) {if (flag[i]) {prime[plen++] = i;}for (j = 0; (j < plen) && (i * prime[j] < nmax); j++) {flag[i * prime[j]] = 0;if (i % prime[j] == 0) {break;}}}
}
void findpFactor(LL n) {int i, te, cnt;te = (int) sqrt(n * 1.0);for (i = 0, len_pfactor = 0; (i < plen) && (prime[i] <= te); i++) {if (n % prime[i] == 0) {cnt = 0;while (n % prime[i] == 0) {cnt++;n /= prime[i];}pfactor[len_pfactor] = (LL) prime[i];cpfactor[len_pfactor++] = cnt;}}if (n > 1) {pfactor[len_pfactor] = n;cpfactor[len_pfactor++] = 1;}
}LL modular_multi(LL a, LL b, LL c) {LL res, temp;res = 0, temp = a % c;while (b) {if (b & 1) {res += temp;if (res >= c) {res -= c;}}temp <<= 1;if (temp >= c) {temp -= c;}b >>= 1;}return res;
}
/*快速幂取余a^b%c*/LL modular_exp(LL a, LL b, LL c) {LL res, temp;res = 1 % c, temp = a % c;while (b) {if (b & 1) {res = modular_multi(res, temp, c);}temp = modular_multi(temp, temp, c);b >>= 1;}return res;
}
int dfs(int depth, LL now) {int i;LL res, temp;if (depth == len_pfactor) {res = modular_exp(proot, now, p);if ((res == 1) && (now != (p - 1))) {return 0;}return 1;}for (i = 0, temp = 1; i <= cpfactor[depth]; i++) {if (!dfs(depth + 1, now * temp)) {return 0;}temp = temp * pfactor[depth];}return 1;
}
void primitive() {findpFactor(p - 1);for (proot = 2;; proot++) {if (dfs(0, 1)) {return;}}
}
LL extend_gcd(LL a, LL b) {LL d, xx;if (b == 0) {x = 1, y = 0;return a;}d = extend_gcd(b, a % b);xx = x;x = y, y = xx - a / b * y;return d;
}int bfindNum(LL key, int n) {int left, right, mid;left = 0, right = n;while (left <= right) {mid = (left + right) >> 1;if (Num[mid].value == key) {return Num[mid].ii;} else if (Num[mid].value > key) {right = mid - 1;} else {left = mid + 1;}}return -1;
}
int cmp(const void *a, const void *b) {num n = *(num *) a;num m = *(num *) b;LL temp = n.value - m.value;if (temp > 0) {return 1;} else if (temp < 0) {return -1;}return 0;
}
/* a^x = b (mod c)*/LL baby_step_giant_step(LL a, LL b, LL c) {int i, j, te;LL temp, xx, aa;te = (int) (sqrt(c * 1.0) + 0.5);for (i = 0, temp = 1 % c; i <= te; i++) {Num[i].ii = i;Num[i].value = temp;temp = temp * a % c;}aa = Num[te].value;qsort(Num, te + 1, sizeof(Num[0]), cmp);for (i = 0, temp = 1; i <= te; i++) {extend_gcd((int) (temp), c);xx = x;xx = xx * b;xx = xx % c + c;x = xx % c;j = bfindNum(x, te + 1);if (j != -1) {return (LL) (i) * te + j;}temp = temp * aa % c;}return -1;
}
int rcmp(const void *a, const void *b) {LL temp = *(LL *) a - *(LL *) b;if (temp > 0) {return 1;} else if (temp < 0) {return -1;}return 0;}
/* ax = b (mod c)*/LL result[1001];
void solve(LL a, LL b, LL c) {int i;LL d;d = extend_gcd(a, c);if (b % d) {puts("-1");return;}b /= d, c /= d;result[0] = ((LL) x * b % c + c) % c;for (i = 1; i < d; i++) {result[i] = result[i - 1] + c;}for (i = 0; i < d; i++) {result[i] = modular_exp(proot, result[i], p);}qsort(result, d, sizeof(result[0]), rcmp);for (i = 0; i < d; i++) {printf("%I64d\n", result[i]);}
}
int main() {
#ifndef ONLINE_JUDGEfreopen("data.in", "r", stdin);
#endifint cas;LL a, b, c;mkprime();cas = 0;/*x^k = n (mod p) */while (~scanf("%I64d %I64d %I64d", &k, &p, &n)) {primitive();b = baby_step_giant_step(proot, n, p);a = k, c = p - 1;printf("case%d:\n", ++cas);solve(a, b, c);}return 0;
}

转载于:https://www.cnblogs.com/xiaoxian1369/archive/2011/10/13/2210216.html

hdu 3930 Broot 二次剩余相关推荐

  1. N次剩余(详解+例题+代码)

    从<国际大学生程序设计大赛算法与实现>中所学 任务: 给定N, a, p, 求出(x^N)%p=a 在模p意义下的所有解x. 说明: 令g为p的原根,因为p为素数,所以phi(p)=p-1 ...

  2. hdu 3589 Jacobi symbol (二次剩余勒让德符号)

    题目链接 题意:交代一下勒让德符号与二次剩余,然后告诉你J(a,n)与L的关系,给定a,n,求J(a,n). 二次剩余的原理我并没有搞太懂= =,想着毕竟不常见,会用板子就好了.在知道如何求勒让德符号 ...

  3. hdu 3589(二次剩余+雅可比符号)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3589: 题意:就是一个裸的雅可比符号: 具体参考:百度百科  百度百科 代码如下: #include ...

  4. HDU 6755 Fibonacci Sum(二次剩余 + 二项式展开)

    Fibonacci Sum 斐波那契通项有an=15((1+52)n−(1−52)n)(15)k∑i=0n((1+52)ic−(1−52)ic)kA=1+52,B=1−52(15)k∑i=0n∑j=0 ...

  5. HDU——1106排序(istringstream的使用、STLvector练习)

    排序 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...

  6. hdu 5438 Ponds 拓扑排序

    Ponds Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/contests/contest_showproblem ...

  7. HDU 1248 寒冰王座(全然背包:入门题)

    HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid=1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票 ...

  8. hdu 1312 Red and Black 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1312 第二条深搜,题目并不难,但是做了我好久好久,由于一个细节,让我赌上了一个晚上的时间. 题目大意: ...

  9. HDU 1429 胜利大逃亡(续) (BFS+位压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others)  ...

最新文章

  1. python链表和树实验报告_关于Python实现树结构和链表结构的一点想法
  2. c语言运算符类型转换,C语言中强制类型转换运算符的独特作用
  3. 关于ASCII字符的那些事儿
  4. Elasticsearch Java Low Level REST Client(通用配置)
  5. 迷你计算机笔记本,迷你笔记本电脑我选择了它,性能不错还超轻便携
  6. Java 集合系列 16 HashSet
  7. Atitit.减少http请求数方案
  8. 用python语言实现人工智能猴子摘香蕉的问题_人工智能 猴子香蕉问题
  9. html暴风粒子代码,魔兽世界课物品代码及gm指令大全(全部整理自网上).doc
  10. Jlink修复指南step by step指导(实践成功) 更新 适用win7-10
  11. node中Async模块的用法
  12. 实验吧-因缺思汀的绕过WriteUp
  13. vue cle新建vue项目
  14. [548]OpenCV之cv2函数
  15. matlab计算绝对值的导数,如何用matlab求带绝对值函数的导数? 你值得一看的技巧...
  16. 数字密码锁(数字逻辑大作业)
  17. 安卓游戏--浅塘之辅助开发(C/S模式)
  18. ElasticSearch中文拼音后无法高亮
  19. C# 仿360悬浮球开发demo程序
  20. bzoj4920: 薄饼切割

热门文章

  1. devstack mysql_devstack 安装openstack newton版
  2. sqlyog-mysql_SQLyog
  3. oracle excute call,oracle – EXECUTE识别存储过程,CALL不识别
  4. 【java】switch的用法介绍
  5. 金融数据分析之财务分析表要填数据怎么办?(学习理财课程后开发的助手工具)
  6. 本周测试服务器角色转移系统仅开放转入,梦幻西游10月8日更新内容一览
  7. B站项目资源过于敏感,稍后删,抓紧保存!!!
  8. YOLO3 动漫人脸识别
  9. python+flask搭建CNN在线识别手写中文网站
  10. 只显示小方格_excel中最有效率的插件——方方格子