hrbeu 1318 X ^ a mod b = c 2 차 남 음
5642 단어 c
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)
/*
* hrbeu1318.c
*
* Created on: 2011-10-13
* Author: bjfuwangzhu
*/
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
#define LL long long
#define nmax 4001
typedef struct num {
int ii, value;
} num;
num Num[nmax];
int flag[nmax], prime[nmax], pfactor[nmax], cpfactor[nmax];
int plen, len_pfactor, k, n, p, proot, x, y;
void mkprime() {
int i, j;
memset(prime, -1, sizeof(prime));
for (i = 2; i < nmax; i++) {
if (prime[i]) {
for (j = i + i; j < nmax; j += i) {
prime[j] = 0;
}
}
}
for (i = 2, plen = 0; i < nmax; i++) {
if (prime[i]) {
prime[plen++] = i;
}
}
}
void findpFactor(int n) {
int i, te, cnt;
te = (int) sqrt(1.0 * n);
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] = prime[i];
cpfactor[len_pfactor++] = cnt;
}
}
if (n > 1) {
pfactor[len_pfactor] = n;
cpfactor[len_pfactor++] = 1;
}
}
/* a^b%c*/
int modular_exp(int a, int b, int c) {
LL res, temp;
res = 1 % c, temp = a % c;
while (b) {
if (b & 1) {
res = res * temp % c;
}
temp = temp * temp % c;
b >>= 1;
}
return (int) 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;
}
}
}
int extend_gcd(int a, int b) {
int 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(int 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;
return n.value - m.value;
}
/* a^x = b (mod c)*/
int baby_step_giant_step(int a, int b, int c) {
int i, j, te, aa;
LL temp, xx;
te = (int) (sqrt(1.0 * c) + 0.5);
for (i = 0, temp = 1 % c; i <= te; i++) {
Num[i].ii = i;
Num[i].value = (int) (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 = (LL) x;
xx = xx * b;
xx = xx % c + c;
x = (int) (xx % c);
j = bfindNum(x, te + 1);
if (j != -1) {
return i * te + j;
}
temp = temp * aa % c;
}
return -1;
}
int rcmp(const void *a, const void *b) {
return *(int *) a - *(int *) b;
}
/* ax = b (mod c)*/
int result[nmax];
void solve(int a, int b, int c) {
int i, d, cc;
d = extend_gcd(a, c);
if (b % d) {
puts("No Solution!");
return;
}
cc = c;
b /= d, c /= d;
result[0] = ((LL) x * b % c + c) % c;
for (i = 1; i < d; i++) {
result[i] = (result[i - 1] + c) % cc;
}
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("%d
", result[i]);
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
int a, b, c;
mkprime();
/*x^k = n (mod p) */
while (~scanf("%d %d %d", &k, &p, &n)) {
primitive();
b = baby_step_giant_step(proot, n, p);
a = k, c = p - 1;
solve(a, b, c);
printf("
");
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 1부이 기사에서는 Entity Framework Core Code First 접근 방식을 사용하는 ASP.NET Core 6.0 WEP API의 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업에 대해 설명합니다. 웹 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.