SGU 261 Discrete Roots (经典K次剩余)
来源:互联网 发布:电驴连不上kad网络 编辑:程序博客网 时间:2024/05/01 15:28
首先求p的原根g, g满足g^(phi(n)/pi) mod n 均不等于1,令g^y=x,g^t=a 得到 g^yk=g^t(modp) (a=0特判) 此式 可转化为 k*y=t(mod(phi(p))); 即 k*y=t(mod(p-1)),接下来就是求g^t=a(mod(p)) ,用babystep 求离散对数的方法求出t ,然后解模线性方程 k*y=t(mod(p-1)), 得到所有的y, y的解的个数为gcd(k,p-1),然后我们就可以求出所有的x,排序输出就行了
#include<cstdio>#include<cstring>#include<queue>#include<vector>#include<iostream>#include<string>#include<sstream>#include<cctype>#include<set>#include<stack>#include<functional>#include<memory>#include<deque>#include<list>#include<cmath>#include<fstream>#include<cstdlib>#include<climits>#include<iomanip>#include<cstring>#include<memory>#include<bitset>#include<algorithm>using namespace std;#define lson l, m, rt<<1#define rson m+1,r,rt<<1|1typedef long long LL;typedef vector<unsigned int> VI;typedef vector<VI> VVI;typedef vector<VVI> VVVI;const int maxn = 40000;const int mod = 1000000007;const int hash_size = 175447;const double pi = acos(-1.0);const double eps = 1e-10;bitset<maxn + 10> a;int p[maxn], size;void init() {int i, j;for (i = 2; i <= 200; ++i)if (!a[i])for (j = i * i; j <= maxn; a[j] = 1, j += i);for (i = 2; i <= 40000; ++i)if (!a[i])p[size++] = i;}int f[maxn], c[maxn], cnt;void spilt(int n) {cnt = 0;int i, t = n;for (i = 0; i < size && p[i] * p[i] <= t; ++i) {if (t % p[i] == 0) {f[cnt] = p[i];while (t % p[i] == 0) {c[cnt]++;t /= p[i];}cnt++;}}if (t > 1) {f[cnt] = t;c[cnt]++;cnt++;}}int factor[maxn], tsize;void dfs(int t, int dep) {if (dep == cnt) {factor[tsize++] = t;return;}for (int i = 0; i <= c[dep]; t *= f[dep], ++i) {dfs(t, dep + 1);}}int POW(LL a, LL b, LL mod) {LL res = 1;while (b) {if (b & 1)res = res * a % mod;a = a * a % mod;b >>= 1;}return (int) res;}int PrimitiveRoot(int n) {if (n == 2)return 1;int i, j;bool flag = false;for (i = 2; i < n; ++i) {flag = true;for (j = 0; j < tsize; ++j) {if (POW(i, factor[j], n) == 1) {flag = false;break;}}if (flag)return i;}return -1;}struct node {LL key;int val, next;node() {}node(LL key, int val, int next) :key(key), val(val), next(next) {}} edge[hash_size + 10];struct HashMap {int i, E;int head[hash_size + 10];void init() {E = 0;memset(head, -1, sizeof(head));}bool insert(LL key, int val) {int u = key % hash_size;for (i = head[u]; ~i; i = edge[i].next) {if (edge[i].key == key)return false;}edge[E] = node(key, val, head[u]);head[u] = E++;return true;}int find(LL key) {int u = key % hash_size;for (i = head[u]; ~i; i = edge[i].next) {if (edge[i].key == key)return edge[i].val;}return -1;}} Hash;LL exgcd(LL a, LL b, LL &x, LL &y) {if (b == 0) {x = 1;y = 0;return a;}LL d = exgcd(b, a % b, x, y);LL t = x;x = y;y = t - (a / b) * y;return d;}LL go(LL A, LL B, LL C) {int i, m = (int) ceil(sqrt(C + 0.0));Hash.init();LL t = 1;Hash.insert(1, 0);for (i = 1; i <= m; ++i) {t = t * A % C;if (t == B)return i;Hash.insert(t, i);}LL P = 1, x, y;for (i = 1; i <= m; ++i) {P = P * t % C;exgcd(P, C, x, y);x *= B;x = (x % C + C) % C;y = Hash.find(x);if (y >= 0)return (int) (i * m + y);}return -1;}LL ans[maxn];int Ccnt;int main() {ios::sync_with_stdio(false);init();int i, p, k, a;scanf("%d%d%d", &p, &k, &a);if (!a) {puts("1");puts("0");return 0;}spilt(p - 1);dfs(1, 0);sort(factor, factor + tsize);--tsize;LL g = PrimitiveRoot(p);LL t = go(g, a, p);LL x, y, b = p - 1, M;LL d = exgcd(k, b, x, y);if (t % d) {puts("0");return 0;}M = b / d;x *= t / d;x = (x % M + M) % M;for (i = 0; i < d; x = x + M, ++i) {ans[Ccnt++] = POW(g, x, p);}sort(ans, ans + Ccnt);printf("%d\n", Ccnt);for (i = 0; i < Ccnt; ++i) {printf("%I64d\n", ans[i]);}return 0;}
- SGU 261 Discrete Roots (经典K次剩余)
- SGU 261 Discrete Roots N次剩余
- SGU 261. Discrete Roots (N次剩余)
- sgu-261 Discrete Roots
- SGU 261 Discrete Roots(原根+高次同余方程+线性同余方程)
- [省选前题目整理][SGU 261]Discrete Roots(扩展欧几里得+中国剩余定理+原根+大步小步算法)
- Discrete Roots
- sgu——261(数论之N次剩余问题)
- UVA 1426 - Discrete Square Roots
- LA 4270 Discrete Square Roots
- uva1426 - Discrete Square Roots 模线性方程
- UVA 1426 - Discrete Square Roots(数论)
- uva 1426 - Discrete Square Roots(拓展欧几里得)
- UVA - 1426 Discrete Square Roots (模方程)
- BZOJ 1420&&BZOJ 1319 Discrete Roots 数论
- [Asia - Hefei - 2008/2009][B:Discrete Square Roots][数论基础]
- sgu261:Discrete Roots(原根+离散对数+扩展欧几里得)
- UVALive 4270 Discrete Square Roots 模方程,数论
- C#操作注册表
- 使用JDBC调用存储过程
- c++ string 转化大小写
- jetty配置
- 开源 免费 java CMS - FreeCMS1.3 标签 channelPath
- SGU 261 Discrete Roots (经典K次剩余)
- 无法解决 equal to 操作中的 **** 和 *******排序规则冲突
- 从xml中提取所有的文本
- 遍历Map
- Validate Binary Search Tree
- JSP九大内置对象
- Android仿QQ微信开场导航以及登陆界面
- 版本规则(收费版-C店)
- IE、FF、Safari、OP不同浏览器兼容报告