多校第七场——1010 Jogging

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值