BZOJ 3243 Clever Y

Description

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

XY mod Z = K

Given XYZ, we all know how to figure out K fast. However, given XZK, 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 XZK (0 ≤ XZK ≤ 109). 
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

5 58 33
2 4 3
0 0 0

Sample Output

9
No Solution

转载自:Navi

当模数 $c$ 不是质数的时候,显然不能直接使用 $BSGS$ 了,考虑它的扩展算法。

前提:同余性质。

令 $d = gcd(a, c)$ , $A = a \cdot d,B = b \cdot d, C = c \cdot d$

则 $a \cdot d \equiv b \cdot d \pmod{c \cdot d}$

等价于 $a \equiv b \pmod{c}$

因此我们可以先消除因子。

对于现在的问题 $(A \cdot d)^x \equiv B \cdot d \pmod{C \cdot d}$ 当我们提出 $d = gcd(a, c)$ ($d \neq 1$)后,原式化为 $A \cdot (A \cdot d)^{x-1} \equiv B \pmod{C}$ 。

即求 $D \cdot A^{x-cnt} \equiv B \pmod{C}$ ,令 $x = i \cdot r-j+cnt$ 。之后的做法就和 $BSGS$ 一样了。

值得注意的是因为这样求出来的解 $x \geq cnt$ 的,但有可能存在解 $x < cnt$ ,所以一开始需要特判。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 typedef long long lol;
  8 int MOD=250000;
  9 lol hash[300001],id[300001];
 10 lol gcd(lol a,lol b)
 11 {
 12   if (!b) return a;
 13   return gcd(b,a%b);
 14 }
 15 void insert(lol x,lol d)
 16 {
 17   lol pos=x%MOD;
 18   while (1)
 19     {
 20       if (hash[pos]==-1||hash[pos]==x)
 21     {
 22       hash[pos]=x;
 23       id[pos]=d;
 24       return;
 25     }
 26       pos++;
 27       if (pos>=MOD) pos-=MOD;
 28     }
 29 }
 30 bool count(lol x)
 31 {
 32   lol pos=x%MOD;
 33   while (1)
 34     {
 35       if (hash[pos]==-1) return 0;
 36       if (hash[pos]==x) return 1;
 37       pos++;
 38       if (pos>=MOD) pos-=MOD;
 39     }
 40 }
 41 lol query(lol x)
 42 {
 43   lol pos=x%MOD;
 44   while (1)
 45     {
 46       if (hash[pos]==x) return id[pos];
 47       pos++;
 48       if (pos>=MOD) pos-=MOD;
 49     }
 50 }
 51 lol qpow(lol x,lol y,lol Mod)
 52 {
 53   lol res=1;
 54   while (y)
 55     {
 56       if (y&1) res=res*x%Mod;
 57       x=x*x%Mod;
 58       y>>=1;
 59     }
 60   return res;
 61 }
 62 lol exBSGS(lol a,lol b,lol Mod)
 63 {lol i;
 64   if (b==1) return 0;
 65   memset(hash,-1,sizeof(hash));
 66   memset(id,0,sizeof(id));
 67   lol cnt=0,d=1,t;
 68   while ((t=gcd(a,Mod))!=1)
 69     {
 70       if (b%t) return -1;
 71       cnt++;
 72       b/=t;Mod/=t;
 73       d=d*(a/t)%Mod;
 74       if (d==b) return cnt;
 75     }
 76     lol tim=ceil(sqrt((double)Mod));
 77       lol tmp=b%Mod;
 78   for (i=0;i<=tim;i++)
 79     {
 80       insert(tmp,i);
 81       tmp=tmp*a%Mod;
 82     }
 83   t=tmp=qpow(a,tim,Mod);
 84   tmp=tmp*d%Mod;
 85   for (i=1;i<=tim;i++)
 86     {
 87       if (count(tmp))
 88     return i*tim-query(tmp)+cnt;
 89       tmp=tmp*t%Mod;
 90     }
 91   return -1;
 92 }
 93 int main()
 94 {lol p,a,b,ans;
 95   while (scanf("%lld%lld%lld",&a,&p,&b))
 96     {
 97       if (p==0) return 0;
 98       if ((ans=exBSGS(a,b,p))==-1) printf("No Solution\n");
 99       else printf("%lld\n",ans);
100     }
101 }

原文地址:https://www.cnblogs.com/Y-E-T-I/p/8413277.html

时间: 2024-10-07 18:45:17

BZOJ 3243 Clever Y的相关文章

poj 3243 Clever Y 高次方程

1 Accepted 8508K 579MS C++ 2237B/** 2 hash的强大,,还是高次方程,不过要求n不一定是素数 3 **/ 4 #include <iostream> 5 #include <cstdio> 6 #include <cmath> 7 #include <cstring> 8 #include <algorithm> 9 using namespace std; 10 long long a,b,n; 11 co

POJ 3243 Clever Y BSGS

Clever Y Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 6861   Accepted: 1676 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, give

【POJ】3243 Clever Y

http://poj.org/problem?id=3243 题意:求$a^y \equiv b \pmod{p}$最小的$y$.(0<=x, y, p<=10^9) #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <iostream> typedef long long ll; using namespace st

POJ 3243 Clever Y 扩展BSGS

http://poj.org/problem?id=3243 这道题的输入数据输入后需要将a和b都%p https://blog.csdn.net/zzkksunboy/article/details/73162229 在大约sqrt( p )的复杂度求出 ( a^x ) % p = b % p中的x 扩展bsgs增加了对p不是素数的情况的处理. 扩展bsgs在处理过a,b,p之后进行bsgs的时候x处理不到num以下的部分,这部分在处理a,b,p的时候处理过了(b=1输出num)所以不用考虑.

POJ 3243 Clever Y Extended-Baby-Step-Giant-Step

题目大意:给定A,B,C,求最小的非负整数x,使A^x==B(%C) 传说中的EXBSGS算法0.0 卡了一天没看懂 最后硬扒各大神犇的代码才略微弄懂点0.0 參考资料: http://quartergeek.com/bsgs/ http://hi.baidu.com/aekdycoin/item/236937318413c680c2cf29d4 这两位写的比較具体0.0 能够用于參考 对拍时发现自己代码各种脑残0.0 伤不起啊 #include<cmath> #include<cstd

Clever Y POJ - 3243 (扩展BSGS)

Clever Y POJ - 3243 题意:给a,c,b,求最小的x使得 ax≡b (mod c). 扩展BSGS算法~ 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <cmath> 5 #define ll long long 6 using namespace std; 7 const int mod=99991; 8 ll head[mod],nex

【EXT-BSGS算法求离散对数】POJ Clever Y 3243

Clever Y Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 7259 Accepted: 1795 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,

【BZOJ1467/2480】Pku3243 clever Y/Spoj3105 Mod EXBSGS

[BZOJ1467/2480]Pku3243 clever Y/Spoj3105 Mod Description 已知数a,p,b,求满足a^x≡b(mod p)的最小自然数x. Input 每个测试文件中最多包含100组测试数据. 每组数据中,每行包含3个正整数a,p,b. 当a=p=b=0时,表示测试数据读入完全. Output 对于每组数据,输出一行. 如果无解,输出“No Solution”(不含引号),否则输出最小自然数解. Sample Input 5 58 33 2 4 3 0 0

【POJ 3243】Clever Y 拓展BSGS

调了一周,我真制杖,,, 各种初始化没有设为1,,,我当时到底在想什么??? 拓展BSGS,这是zky学长讲课的课件截屏: 是不是简单易懂.PS:聪哥说“拓展BSGS是偏题,省选不会考,信我没错”,那是因为聪哥早就会了,所以他觉得学这个没用,信他才怪233 #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef lo