赞
踩
A train goes back and forth between Town A and Town B. It departs Town A at time 0 and then repeats the following:
More formally, these intervals of time are half-open, that is, for each n=0,1,2,…:
Takahashi is thinking of taking this train to depart Town
A at time 0 and getting off at Town B. After the departure, he will repeat the following:
Again, these intervals of time are half-open, that is, for each n=0,1,2,…:
He can get off the train at Town B if it is stopping at Town B and he is awake.Determine whether he can get off at Town B. If he can, find the earliest possible time to do so.Under the constraints of this problem, it can be proved that the earliest time is an integer.
You are given T cases. Solve each of them.
3
5 2 7 6
1 1 3 1
999999999 1 1000000000 1
Copy
20
infinity
1000000000999999999
拓展欧几里得~
题目就是求一个同余方程组:
{
t
≡
t
1
(
m
o
d
(
2
X
+
2
Y
)
)
t
≡
t
2
(
m
o
d
(
P
+
Q
)
)
{t≡t1(mod (2X+2Y))t≡t2(mod (P+Q))
两式相减可以得:
(
2
X
+
2
Y
)
x
−
(
P
+
Q
)
y
=
t
2
−
t
1
(2X+2Y)x-(P+Q)y=t2-t1
(2X+2Y)x−(P+Q)y=t2−t1
因为题目中的
Y
,
Q
Y,Q
Y,Q 都比较小,所以
t
1
,
t
2
t1,t2
t1,t2 可以暴力遍历,上式可以通过拓展欧几里得定理求得一个特解
x
0
x_0
x0,所以可以得到
t
t
t 的一个特解
t
0
=
(
2
X
+
2
Y
)
∗
x
0
+
t
1
t_0=(2X+2Y)*x_0+t1
t0=(2X+2Y)∗x0+t1,那么通解就是
t
=
t
0
+
L
C
M
(
2
X
+
2
Y
,
P
+
Q
)
t=t_0+LCM(2X+2Y,P+Q)
t=t0+LCM(2X+2Y,P+Q),题目要求最小的正整数解,只需要将特解
t
0
t_0
t0 对
L
C
M
(
2
X
+
2
Y
,
P
+
Q
)
LCM(2X+2Y,P+Q)
LCM(2X+2Y,P+Q) 取模即可~
这题唯一的坑点就是会爆
l
l
ll
ll,所以在最后算答案的时候要加快速乘,AC代码如下:
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll X, Y, ans, LCM, x, y, p, q, i, j; void Gcd(ll A, ll B, ll &gcd) { if (B) { Gcd(B, A % B, gcd); ll t = X; X = Y; Y = t - (A / B) * Y; } else { gcd = A; X = 1, Y = 0; } } ll f(ll a, ll b, ll mod) { ll k = 0; while (b) { if (b & 1) k = (k + a) % mod; a = (a + a) % mod; b >>= 1; } return k; } void exgcd(ll A, ll B, ll C) { ll gcd; Gcd(A, B, gcd); if (C % gcd) return; else { X = X * (C / gcd); if (X < 0) X = (LCM - (-X) % LCM) % LCM; ans = min(ans, (f(2 * x + 2 * y, X, LCM) + i) % LCM); } } int main() { int t; cin >> t; while (t--) { ans = INT64_MAX; cin >> x >> y >> p >> q; LCM = (2 * x + 2 * y) / __gcd(2 * x + 2 * y, p + q) * (p + q); for (i = x; i < x + y; i++) { for (j = p; j < p + q; j++) { exgcd(2 * x + 2 * y, -p - q, j - i); } } if (ans == INT64_MAX) cout << "infinity\n"; else cout << ans << endl; } return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。