POJ 3243:Clever Y BSGS
2016-04-29 09:48
375 查看
Clever Y
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
Sample Output
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;
}
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 7782 | Accepted: 1939 |
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;
}
相关文章推荐
- PS制作可爱的大头头像效果
- Android EditText点击两次才能响应,解决办法
- android事件分发之ViewGroup篇
- 使用CD-K算法实现RBM
- 触屏拉动页面
- 每日记录 2016-4-29 HTML5本地存储
- 0429 Scrum团队成立与第6-7章读后感
- 百度地图中循环输出坐标点信息是重复的问题解决方法
- Python过滤列表用法实例分析
- 四种常见 Git 工作流比较
- 二叉树
- 水水笔
- CentOS 7 yum install mysql
- Mysql InnoDB存储引擎有三大特性之一的 - 插入缓冲(insert buffer)
- VIM
- Java:String和Date、Timestamp之间的转换
- 链接脚本学习
- mybatis_generator_逆向工程
- 一种怪异的节点删除方式
- nginx proxy的使用