[BZOJ 1467] [POJ 3243] clever Y
阿新 • • 發佈:2018-12-12
題目描述
小Y發現,數學中有一個很有趣的式子: 給出、、,我們都知道如何很快的計算。但是如果給出、、,你是否知道如何快速的計算呢?
輸入輸出格式
輸入格式
本題由多組資料(不超過20組),每組測試資料包含一行三個整數、、()。 輸入檔案一行由三個空格隔開的結尾。
輸出格式
對於每組資料:如果無解則輸出一行No Solution
,否則輸出一行一個整數,使得其滿足,如果有多個解輸出最小的一個。
輸入輸出樣例
輸入樣例#1:
5 58 33
2 4 3
0 0 0
輸出樣例#1:
9
No Solution
解題分析
一道擴充套件的板題。
一般的只能解決且為質數的情況, 如果不互質就涼涼了。
設, 那麼我們可以將這個式子拆開成, 如此反覆操作最後可以得到。 這時候就可以用普通的搞操作了。
不過顯然我們現在的, 所以我們暴力列舉的情況就好。
程式碼如下:
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <cctype>
#include <map>
#define W while
#define IN inline
#define gc getchar()
#define R register
template <class T>
IN void in(T &x)
{
x = 0; R char c = gc;
for (; !isdigit(c); c = gc);
for (; isdigit(c); c = gc)
x = (x << 1) + (x << 3) + c - 48;
}
std::map <int, int> mp;
int exgcd(R int a, R int b, int &x, int &y)
{
if(!b) return x = 1, y = 0, a;
int ret = exgcd(b, a % b, x, y);
int buf = x; x = y, y = buf - a / b * y;
return ret;
}
IN int EXBSGS(R int A, R int B, R int MOD)
{
if(MOD == 1) if(!B) return 0; else return -1;
if(B == 1) if(A) return 0; else return -1;
if(!(A % MOD)) if(!B) return 1; else return -1;
int num = 0, now = 1, seg = 1, gcd, x, y, bd = std::ceil(std::sqrt(MOD));
mp.clear();
W ((gcd = exgcd(A, MOD, x, y)) > 1)
{
if(B % gcd) return -1;
B /= gcd, MOD /= gcd; ++num;
now = 1ll * now * A / gcd % MOD;
}
for (R int i = 0, val = 1; i <= num; ++i, val = 1ll * val * A % MOD)
if(val == B) return i;
for (R int i = 0; i < bd; ++i, seg = 1ll * seg * A % MOD) if(!mp.count(seg)) mp[seg] = i;
for (R int i = 0; i < bd; ++i, now = 1ll * now * seg % MOD)
{
gcd = exgcd(now, MOD, x, y);
x = (1ll * x * B % MOD + MOD) % MOD;
if(mp.count(x)) return i * bd + mp[x] + num;
}
return -1;
}
int main(void)
{
R int A, B, MOD, ans;
W (~scanf("%d%d%d", &A, &MOD, &B))
{
if(!(A | B | MOD)) break;
ans = EXBSGS(A, B, MOD);
if(ans < 0) puts("No Solution");
else printf("%d\n", ans);
}
}