SGU 261. Discrete Roots (N次剩余)
N次剩余
题目:http://acm.sgu.ru/problem.php?
contest=0&problem=261
题意:给定n,a,p 求出x^n ≡ a(mod p)在模p意义下的全部解,当中p是素数
说明:
代码:
/*
ID: wuqi9395@126.com
PROG:
LANG: C++
*/
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<fstream>
#include<cstring>
#include<ctype.h>
#include<iostream>
#include<algorithm>
#define INF (1<<30)
#define PI acos(-1.0)
#define mem(a, b) memset(a, b, sizeof(a))
#define rep(i, n) for (int i = 0; i < n; i++)
#define debug puts("===============")
using namespace std;
typedef long long ll; //高速幂
ll pow_mod(ll a, ll n, ll m) {
ll res = 1;
while(n) {
if (n & 1) res = res * a % m;
n >>= 1;
a = a * a % m;
}
return res;
} //求原根
vector<ll> a;
bool g_test(ll g, ll p) {
for (ll i = 0; i < a.size(); i++)
if (pow_mod(g, (p - 1) / a[i], p) == 1) return 0;
return 1;
}
ll primitive_root(ll p) {
a.clear();
ll tmp = p - 1;
for (ll i = 2; i <= tmp / i; i++) if (tmp % i == 0) { //这里还能够用筛素数优化
a.push_back(i);
while(tmp % i == 0) tmp /= i;
}
if (tmp != 1) a.push_back(tmp);
ll g = 1;
while(true) {
if (g_test(g, p)) return g;
g++;
}
} // 求离散对数
#define N 111111
struct node {
ll x, id;
bool operator < (const node & T) const {
if (x == T.x) return id < T.id;
return x < T.x;
}
}E[N];
ll discrete_log(ll x, ll n, ll m) {
int s = sqrt(m + 0.5);
for (; (ll) s * s <= m; ) s++;
ll cur = 1;
node tmp;
for (int i = 0; i < s; i++) {
tmp.id = i, tmp.x = cur;
E[i] = tmp;
cur = cur * x % m;
}
sort(E, E + s);
ll mul = pow_mod(cur, m - 2, m) % m; // mul = 1 / (x^s)
cur = 1;
for (int i = 0; i < s; i++) {
ll more = (ll) n * cur % m;
tmp.id = -1, tmp.x = more;
int pos = lower_bound(E, E + s, tmp) - E;
if (E[pos].x == more) return i * s + E[pos].id;
cur = cur * mul % m;
}
return -1;
} //扩展欧几里得
ll extend_gcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
else {
ll r = extend_gcd(b, a % b, y, x);
y -= x * (a / b);
return r;
}
} //N次剩余
//给定n,a,p 求出x^n ≡ a(mod p)在模p意义下的全部解,当中p是素数
vector<ll> residue(ll p, ll n, ll a) {
vector<ll> ret;
if (a == 0) {
ret.push_back(0);
return ret;
}
ll g = primitive_root(p);
ll m = discrete_log(g, a, p);
if (m == -1) return ret;
ll A = n, B = p - 1, C = m, x, y;
ll d = extend_gcd(A, B, x, y);
if (C % d != 0) return ret;
x = x * (C / d) % B;
ll delta = B / d;
for (int i = 0; i < d; i++) {
x = ((x + delta) % B + B) % B;
ret.push_back(pow_mod(g, x, p));
}
sort(ret.begin(), ret.end());
ret.erase(unique(ret.begin(), ret.end()), ret.end());
return ret;
}
int main () {
ll n, a, p;
scanf("%lld%lld%lld", &p, &n, &a);
vector<ll> ret = residue(p, n, a);
printf("%d\n", ret.size());
for (int i = 0; i < ret.size(); i++) printf("%d ", ret[i]);
return 0;
}
SGU 261. Discrete Roots (N次剩余)的更多相关文章
- SGU 261. Discrete Roots
给定\(p, k, A\),满足\(k, p\)是质数,求 \[x^k \equiv A \mod p\] 不会... upd:3:29 两边取指标,是求 \[k\text{ind}_x\equiv ...
- HDU1163 Eddy's digital Roots【九剩余定理】
Eddy's digital Roots Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Oth ...
- sgu 261
学习了元根的一些知识,哈哈. 总结一下: 几个概念: 阶:对于模数m和整数a,并且gcd(m,a)==1,那么定义a在模m下的阶r为满足ar=1 mod m的最小正整数. 性质1:r in [1,ph ...
- 一些数论概念与算法——从SGU261谈起
话说好久没来博客上面写过东西了,之前集训过于辛苦了,但有很大的收获,我觉得有必要把它们拿出来总结分享.之前一直是个数论渣(小学初中没好好念过竞赛的缘故吧),经过一道题目对一些基础算法有了比较深刻的理解 ...
- UVA 1426 - Discrete Square Roots(数论)
UVA 1426 - Discrete Square Roots 题目链接 题意:给定X, N. R.要求r2≡x (mod n) (1 <= r < n)的全部解.R为一个已知解 思路: ...
- UVa 1426 Discrete Square Roots (扩展欧几里德)
题意:给定 x,n,r,满足 r2 ≡ x mod(n) ,求在 0 ~ n 内满足 rr2 ≡ x mod(n) 的所有的 rr. 析:很明显直接是肯定不行了,复杂度太高了. r2 ≡ x mod( ...
- Discrete Square Roots UVALive - 4270(拓展欧几里得)
a≡b(mod n)的含义是“a和b除以n的余数相同”,其充要条件是“a-b是n的整数倍”: 求所有满足条件r^2=x(mod m)的r 题目已经给定了一个初始的r,x,m #include < ...
- UVALive 4270 Discrete Square Roots
题目描述: 在已知一个离散平方根的情况下,按照从小到大的顺序输出其他所有的离散平方根. 在模n意义下,非负整数x的离散平方根是满足0<=r<n且r2=x(mod n)的整数r. 解题思路: ...
- UVALive - 4270 Discrete Square Roots (扩展欧几里得)
给出一组正整数$x,n,r$,使得$r^2\equiv x(mod\: n)$,求出所有满足该等式的$r$. 假设有另一个解$r'$满足条件,则有$r^2-r'^2=kn$ 因式分解,得$(r+r') ...
随机推荐
- 指定PHP编码
有时候我们写好的PHP页面在网页中打开是乱码的,就需要指定编码,即加入代码: header("content-type:text/html;charset=utf-8"); 位置图 ...
- python3+beautifulSoup4.6抓取某网站小说(二)基础功能设计
本章学习内容:1.网页编码还原读取2.功能设计 stuep1:网页编码还原读取 本次抓取对象: http://www.cuiweijuxs.com/jingpinxiaoshuo/ 按照第一篇的代码来 ...
- ios摇一摇功能
在 UIResponder中存在这么一套方法 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event __OSX_A ...
- RN code push自定义弹框
最近在弄react native的code push热更新问题.开始是用的后台默默更新配置.由于微软服务器速度问题,经常遇到用户一直在下载中问题.而用户也不知道代码需要更新才能使用新功能,影响了正常业 ...
- c++复合类型
1.数组 数组存储同类型的值: 数组使用下标或索引对元素进行标号,从0开始编号: 只能在定义数组时才能使用初始化,此后就不可以了,也不能将一个数组赋给另一个数组: 初始化数组时,提供的值可以少于数组元 ...
- CentOS7-wget命令
Wget主要用于下载文件,在安装软件时会经常用到,以下对wget做简单说明.转载自:https://www.cnblogs.com/lxz88/p/6278268.html 1.下载单个文件:wget ...
- C#NumberFormatInfo类
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA0sAAAD2CAIAAACImosXAAAgAElEQVR4nOy9V3Nk13X+vTt3owPSJJ ...
- Java线上应用故障排查
线上故障主要2种: CPU利用率很高, 内存占用率很大 一.CPU利用率很高 1. top查询那个进程CPU使用率高 2. 显示进程列表 ps -mp pid -o THREAD,tid,time 找 ...
- vim 编辑器使用法则
vim 编辑器使用法则 Vi编辑器有3种使用模式:一般模式.编辑模式和命令模式. $SHELL:查看当前默认shell类型 $BASH_VERSION:查看当前shell版本 3.一般模式: 光标移 ...
- ExecutorService 线程池 (转发)
1.ExecutorService java.util.concurrent.ExecutorService 接口.用来设置线程池并执行多线程任务.它有以下几个方法. Future<?> ...