hdu 3930 Broot 二次剩余
模素数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 二次剩余相关推荐
- N次剩余(详解+例题+代码)
从<国际大学生程序设计大赛算法与实现>中所学 任务: 给定N, a, p, 求出(x^N)%p=a 在模p意义下的所有解x. 说明: 令g为p的原根,因为p为素数,所以phi(p)=p-1 ...
- hdu 3589 Jacobi symbol (二次剩余勒让德符号)
题目链接 题意:交代一下勒让德符号与二次剩余,然后告诉你J(a,n)与L的关系,给定a,n,求J(a,n). 二次剩余的原理我并没有搞太懂= =,想着毕竟不常见,会用板子就好了.在知道如何求勒让德符号 ...
- hdu 3589(二次剩余+雅可比符号)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3589: 题意:就是一个裸的雅可比符号: 具体参考:百度百科 百度百科 代码如下: #include ...
- 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 ...
- HDU——1106排序(istringstream的使用、STLvector练习)
排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- hdu 5438 Ponds 拓扑排序
Ponds Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/contests/contest_showproblem ...
- HDU 1248 寒冰王座(全然背包:入门题)
HDU 1248 寒冰王座(全然背包:入门题) http://acm.hdu.edu.cn/showproblem.php?pid=1248 题意: 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票 ...
- hdu 1312 Red and Black 解题报告
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1312 第二条深搜,题目并不难,但是做了我好久好久,由于一个细节,让我赌上了一个晚上的时间. 题目大意: ...
- HDU 1429 胜利大逃亡(续) (BFS+位压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429 胜利大逃亡(续) Time Limit: 4000/2000 MS (Java/Others) ...
最新文章
- python链表和树实验报告_关于Python实现树结构和链表结构的一点想法
- c语言运算符类型转换,C语言中强制类型转换运算符的独特作用
- 关于ASCII字符的那些事儿
- Elasticsearch Java Low Level REST Client(通用配置)
- 迷你计算机笔记本,迷你笔记本电脑我选择了它,性能不错还超轻便携
- Java 集合系列 16 HashSet
- Atitit.减少http请求数方案
- 用python语言实现人工智能猴子摘香蕉的问题_人工智能 猴子香蕉问题
- html暴风粒子代码,魔兽世界课物品代码及gm指令大全(全部整理自网上).doc
- Jlink修复指南step by step指导(实践成功) 更新 适用win7-10
- node中Async模块的用法
- 实验吧-因缺思汀的绕过WriteUp
- vue cle新建vue项目
- [548]OpenCV之cv2函数
- matlab计算绝对值的导数,如何用matlab求带绝对值函数的导数? 你值得一看的技巧...
- 数字密码锁(数字逻辑大作业)
- 安卓游戏--浅塘之辅助开发(C/S模式)
- ElasticSearch中文拼音后无法高亮
- C# 仿360悬浮球开发demo程序
- bzoj4920: 薄饼切割
热门文章
- devstack mysql_devstack 安装openstack newton版
- sqlyog-mysql_SQLyog
- oracle excute call,oracle – EXECUTE识别存储过程,CALL不识别
- 【java】switch的用法介绍
- 金融数据分析之财务分析表要填数据怎么办?(学习理财课程后开发的助手工具)
- 本周测试服务器角色转移系统仅开放转入,梦幻西游10月8日更新内容一览
- B站项目资源过于敏感,稍后删,抓紧保存!!!
- YOLO3 动漫人脸识别
- python+flask搭建CNN在线识别手写中文网站
- 只显示小方格_excel中最有效率的插件——方方格子