【POJ 3243-Clever Y】 与【POJ 2417-Discrete Logging】(解高次同余方程 Baby-Step-Gaint-Step)

太过爱你忘了你带给我的痛 2022-09-24 15:25 192阅读 0赞

Clever Y














Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 7969   Accepted: 1986

Description

Little Y finds there is a very interesting formula in mathematics:

XY mod Z = K

Given X, Y, Z, we all know how to figure out K fast. However, given X, Z, K, could you figure out Y fast?

Input

Input data consists of no more than 20 test cases. For each test case, there would be only one line containing 3 integers X, Z, K (0 ≤ X, Z, K ≤ 10 9).
Input file ends with 3 zeros separated by spaces.

Output

For each test case output one line. Write “No Solution” (without quotes) if you cannot find a feasible Y (0 ≤ Y < Z). Otherwise output the minimum Y you find.

Sample Input

  1. 5 58 33
  2. 2 4 3
  3. 0 0 0

Sample Output

  1. 9
  2. No Solution

Source

POJ Monthly—2007.07.08, Guo, Huayang

题目意思:

已知X,Z和K,求解Y满足: (X^Y) mod Z=K,即 (X^Y)≡K(mod Z)。

解题思路:

模板题,解高次同余方程。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<cmath>
  5. #include<malloc.h>
  6. using namespace std;
  7. typedef long long ll;
  8. #define maxn 100000
  9. struct Hash
  10. {
  11. int a,b,next;
  12. } hash[2*maxn];
  13. int flag[maxn];
  14. int top,idx;
  15. void ins(int a,int b)
  16. {
  17. int k=b&maxn;
  18. if(flag[k]!=idx)
  19. {
  20. flag[k]=idx;
  21. hash[k].next=-1;
  22. hash[k].a=a;
  23. hash[k].b=b;
  24. return;
  25. }
  26. while(hash[k].next!=-1)
  27. {
  28. if(hash[k].b==b) return;
  29. k=hash[k].next;
  30. }
  31. hash[k].next=++top;
  32. hash[top].next=-1;
  33. hash[top].a=a;
  34. hash[top].b=b;
  35. }
  36. int find(int b)
  37. {
  38. int k=b&maxn;
  39. if(flag[k]!=idx) return -1;
  40. while(k!=-1)
  41. {
  42. if(hash[k].b==b) return hash[k].a;
  43. k=hash[k].next;
  44. }
  45. return -1;
  46. }
  47. int gcd(int a,int b)
  48. {
  49. return b==0?a:gcd(b,a%b);
  50. }
  51. int exgcd(int a,int b,int &x,int &y)
  52. {
  53. int t,d;
  54. if(!b)
  55. {
  56. x=1,y=0;
  57. return a;
  58. }
  59. d=exgcd(b,a%b,x,y);
  60. t=x,x=y,y=t-a/b*y;
  61. return d;
  62. }
  63. int inval(int a,int b,int n)
  64. {
  65. int x,y,e;
  66. exgcd(a,n,x,y);
  67. e=(long long)x*b%n;
  68. return e<0?e+n:e;
  69. }
  70. int pow_mod(long long a,int b,int c)
  71. {
  72. long long ret=1%c;
  73. a%=c;
  74. while(b)
  75. {
  76. if(b&1) ret=ret*a%c;
  77. a=a*a%c;
  78. b>>=1;
  79. }
  80. return ret;
  81. }
  82. int BabyStep(int A,int B,int C)
  83. {
  84. top=maxn;
  85. ++idx;
  86. long long buf=1%C,D=buf,K;
  87. int i,d=0,tmp;
  88. for(i=0; i<=100; buf=buf*A%C,++i)
  89. if(buf==B) return i;
  90. while((tmp=gcd(A,C))!=1)
  91. {
  92. if(B%tmp) return -1;
  93. ++d;
  94. C/=tmp;
  95. B/=tmp;
  96. D=D*A/tmp%C;
  97. }
  98. int M=(int)ceil(sqrt((double)C));
  99. for(buf=1%C,i=0; i<=M; buf=buf*A%C,++i)
  100. ins(i,buf);
  101. for(i=0,K=pow_mod((long long)A,M,C); i<=M; D=D*K%C,++i)
  102. {
  103. tmp=inval((int)D,B,C);
  104. int w;
  105. if(tmp>=0&&(w=find(tmp))!=-1)
  106. return i*M+w+d;
  107. }
  108. return -1;
  109. }
  110. int main()
  111. {
  112. ios::sync_with_stdio(false);
  113. cin.tie(0);
  114. int A,B,C;
  115. while(cin>>A>>C>>B,A||B||C)
  116. {
  117. B%=C;
  118. int tmp=BabyStep(A,B,C);
  119. if(tmp<0) puts("No Solution");
  120. else cout<<tmp<<endl;
  121. }
  122. return 0;
  123. }
  124. /**
  125. 5 58 33
  126. 2 4 3
  127. 0 0 0
  128. **/

Discrete Logging














Time Limit: 5000MS   Memory Limit: 65536K
Total Submissions: 5064   Accepted: 2301

Description

Given a prime P, 2 <= P < 2 31, an integer B, 2 <= B < P, and an integer N, 1 <= N < P, compute the discrete logarithm of N, base B, modulo P. That is, find an integer L such that

  1. BL == N (mod P)

Input

Read several lines of input, each containing P,B,N separated by a space.

Output

For each line print the logarithm on a separate line. If there are several, print the smallest; if there is none, print “no solution”.

Sample Input

  1. 5 2 1
  2. 5 2 2
  3. 5 2 3
  4. 5 2 4
  5. 5 3 1
  6. 5 3 2
  7. 5 3 3
  8. 5 3 4
  9. 5 4 1
  10. 5 4 2
  11. 5 4 3
  12. 5 4 4
  13. 12345701 2 1111111
  14. 1111111121 65537 1111111111

Sample Output

  1. 0
  2. 1
  3. 3
  4. 2
  5. 0
  6. 3
  7. 1
  8. 2
  9. 0
  10. no solution
  11. no solution
  12. 1
  13. 9584351
  14. 462803587

Hint

The solution to this problem requires a well known result in number theory that is probably expected of you for Putnam but not ACM competitions. It is Fermat’s theorem that states

  1. B(P-1) == 1 (mod P)

for any prime P and some other (fairly rare) numbers known as base-B pseudoprimes. A rarer subset of the base-B pseudoprimes, known as Carmichael numbers, are pseudoprimes for every base between 2 and P-1. A corollary to Fermat’s theorem is that for any m

  1. B(-m) == B(P-1-m) (mod P) .

Source

Waterloo Local 2002.01.26

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdio>
  4. #include<cmath>
  5. #include<malloc.h>
  6. using namespace std;
  7. typedef long long ll;
  8. #define maxn 65535//这里写大于65535的数会WA
  9. struct Hash
  10. {
  11. ll a,b,next;
  12. } hash[2*maxn];
  13. ll flag[maxn];
  14. ll top,idx;
  15. void ins(ll a,ll b)
  16. {
  17. ll k=b&maxn;
  18. if(flag[k]!=idx)
  19. {
  20. flag[k]=idx;
  21. hash[k].next=-1;
  22. hash[k].a=a;
  23. hash[k].b=b;
  24. return;
  25. }
  26. while(hash[k].next!=-1)
  27. {
  28. if(hash[k].b==b) return;
  29. k=hash[k].next;
  30. }
  31. hash[k].next=++top;
  32. hash[top].next=-1;
  33. hash[top].a=a;
  34. hash[top].b=b;
  35. }
  36. ll find(ll b)
  37. {
  38. ll k=b&maxn;
  39. if(flag[k]!=idx) return -1;
  40. while(k!=-1)
  41. {
  42. if(hash[k].b==b) return hash[k].a;
  43. k=hash[k].next;
  44. }
  45. return -1;
  46. }
  47. ll gcd(ll a,ll b)
  48. {
  49. return b==0?a:gcd(b,a%b);
  50. }
  51. ll exgcd(ll a,ll b,ll &x,ll &y)
  52. {
  53. ll t,d;
  54. if(!b)
  55. {
  56. x=1,y=0;
  57. return a;
  58. }
  59. d=exgcd(b,a%b,x,y);
  60. t=x,x=y,y=t-a/b*y;
  61. return d;
  62. }
  63. ll inval(ll a,ll b,ll n)
  64. {
  65. ll x,y,e;
  66. exgcd(a,n,x,y);
  67. e=(long long)x*b%n;
  68. return e<0?e+n:e;
  69. }
  70. ll pow_mod(long long a,ll b,ll c)
  71. {
  72. long long ret=1%c;
  73. a%=c;
  74. while(b)
  75. {
  76. if(b&1) ret=ret*a%c;
  77. a=a*a%c;
  78. b>>=1;
  79. }
  80. return ret;
  81. }
  82. ll BabyStep(ll A,ll B,ll C)
  83. {
  84. top=maxn;
  85. ++idx;
  86. long long buf=1%C,D=buf,K;
  87. ll i,d=0,tmp;
  88. for(i=0; i<=100; buf=buf*A%C,++i)
  89. if(buf==B) return i;
  90. while((tmp=gcd(A,C))!=1)
  91. {
  92. if(B%tmp) return -1;
  93. ++d;
  94. C/=tmp;
  95. B/=tmp;
  96. D=D*A/tmp%C;
  97. }
  98. ll M=(ll)ceil(sqrt((double)C));
  99. for(buf=1%C,i=0; i<=M; buf=buf*A%C,++i)
  100. ins(i,buf);
  101. for(i=0,K=pow_mod((long long)A,M,C); i<=M; D=D*K%C,++i)
  102. {
  103. tmp=inval((ll)D,B,C);
  104. ll w;
  105. if(tmp>=0&&(w=find(tmp))!=-1)
  106. return i*M+w+d;
  107. }
  108. return -1;
  109. }
  110. int main()
  111. {
  112. ios::sync_with_stdio(false);
  113. cin.tie(0);
  114. ll A,B,C;
  115. while(cin>>C>>A>>B)
  116. {
  117. B%=C;
  118. ll tmp=BabyStep(A,B,C);
  119. if(tmp<0) puts("no solution");
  120. else cout<<tmp<<endl;
  121. }
  122. return 0;
  123. }
  124. /**
  125. 5 2 1
  126. 5 2 2
  127. 5 2 3
  128. 5 2 4
  129. 5 3 1
  130. 5 3 2
  131. 5 3 3
  132. 5 3 4
  133. 5 4 1
  134. 5 4 2
  135. 5 4 3
  136. 5 4 4
  137. 12345701 2 1111111
  138. 1111111121 65537 1111111111
  139. **/

发表评论

表情:
评论列表 (有 0 条评论,192人围观)

还没有评论,来说两句吧...

相关阅读