Problem Description
Notice:Don’t output extra spaces at the end of one line.
Dodo bird is jogging on an infinite 2-d plane, starting from (x0,y0). For a point(x,y), it is regarded as good if and only if gcd(x,y)>1.
Dodo bird will walk infinite steps on the plane under the following strategy:
Assume he is currently at (x,y), let S be the set of good points among (x−1,y−1),(x−1,y),(x−1,y+1),(x,y−1),(x,y+1),(x+1,y−1),(x+1,y),(x+1,y+1), z be the size of S. He has a probability of 1z+1 to stay in (x,y), and he also has a probility of zz+1 to move to a point in S. If he chooses to move, the probility of going to any point in S is equal.
Define pt as the probability of coming back to (x0,y0) after walking t steps, please calculate limt→∞pt. It is guaranteed that the answer always exists.
Input
The first line contains an integer T(1≤T≤1000), indicating the number of test cases.
Each test case has one line, which contains two integers x,y(2≤x0,y0≤1012), indicating the position of the start point. It is guaranteed that gcd(x0,y0)>1.
Output
T lines, each line contains an irreducible fraction, indicating the answer.
Sample Input
3
18 16
18 6
18 8
Sample Output
0/1
1/1
2/7
首先如果起点与对角线连通,那么答案就是 。否则,可以证明起点所在连通块的大小不会很大,暴力 出所有 点建图即可。建出图来之后,答案就是 “起点的度数+1” 除以 “总度数+n”,其中 表示连通块大小,证明可以考 虑:假设极限存在且唯一,那么此答案满足对应的约束关系。至于证明极限的存在性,需要涉及关于邻接矩阵的特 征值等内容,可以自行查阅“图上随机游走”相关书籍文献。
证明连通块大小不会很大的过程:对于一个点 ,假设其不与对角线连通,那么不妨设 。设 满足 是相邻的两个质数,那么对于 和 这两条线来说,地图上对角线下方的部 分全部为墙。因此可以证明连通块大小一定不会大于 ,其中 表示不大于 的相邻质数之差的最大值,而 只有几百。同时这是一个极松的估算,实际测试的结果远远小于这个数字。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int temp[8][2] = { 0,1,0,-1,1,0,-1,0,1,1,-1,-1,-1,1,1,-1 };
set<pair<ll, ll>>vis;
void bfs(ll x, ll y)
{
int A1 = 0, A2 = 0;
queue<pair<ll, ll>>q;
q.emplace(x, y);
vis.emplace(x, y);
while (q.size())
{
tie(x, y) = q.front();
q.pop();
if (x == y)
{
A1 = 0, A2 = 1;
break;
}
A2++;
for (int i = 0; i < 8; i++)
{
ll x_ = x + temp[i][0];
ll y_ = y + temp[i][1];
if (__gcd(x_, y_) == 1)
{
continue;
}
A2++;
if (vis.count(make_pair(x_, y_))) {
continue;
}
vis.emplace(x_, y_);
q.emplace(x_, y_);
}
if (!A1)
{
A1 = A2;
}
}
int gcd = __gcd(A1, A2);
A1 /= gcd;
A2 /= gcd;
printf("%d/%d\n", A1, A2);
}
int main()
{
int T;
cin >> T;
while (T--)
{
ll x, y;
cin >> x >> y;
bfs(x, y);
}
return 0;
}