您的位置:首页 > 其它

POJ 3243:Clever Y BSGS

2016-04-29 09:48 375 查看
Clever Y

Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 7782 Accepted: 1939
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 ≤ 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


m=sqrt(z),将b^0一直到b^(m-1)次方插入到哈希表中,然后不断枚举i*m,查找是否有x^(i*m)=k*x^(j) mod z。

代码:

#pragma warning(disable:4996)
#include <iostream>
#include <functional>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;

#define INF 0x333f3f3f
#define repp(i, n, m) for (int i = n; i <= m; i++)
#define rep(i, n, m) for (int i = n; i < m; i++)
#define sa(n) scanf("%d", &(n))

const int maxn = 1e6 + 7;
const double PI = acos(-1.0);
const int mod = 1e9 + 7;

struct ed
{
ll next;
ll val;
ll id;
}edge[maxn];

int num;
int head[maxn];

void insert(ll x, ll y)
{
ll k = x%maxn;
num++;
edge[num].val = x;
edge[num].id = y;
edge[num].next = head[k];
head[k] = num;
}

ll find(ll x)
{
int k = x%maxn;
for (int i = head[k]; i != -1; i = edge[i].next)
if (edge[i].val == x)
return edge[i].id;
return -1;
}

ll x, z, k;
void solve()
{
ll i, j, m;

num = 0;
memset(edge, -1, sizeof(edge));
memset(head, -1, sizeof(head));

m = sqrt(1.0*z);
if (k == 1)
{
printf("0\n");
return;
}
ll p = 1;
for (i = 0; i < m; i++, p = p*x%z)
{
insert(p*k%z, i);
}
ll xx = 1;

for (i = m;; i += m)
{
ll pos = find(xx = p*xx%z);
if (pos != -1)
{
printf("%lld\n", i - pos);
return;
}
if (i > z)
break;
}
printf("No Solution\n");
}

int main()
{
#ifndef ONLINE_JUDGE
freopen("i.txt", "r", stdin);
freopen("o.txt", "w", stdout);
#endif

while (scanf("%lld%lld%lld", &x, &z, &k) != EOF)
{
if (x == 0 && z == 0 && k == 0)
break;
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: