Content
有两个数 \(a,b\),执行如下操作:
- 如果 \(a,b\) 中有一个数是 \(0\),结束操作,否则跳到操作 \(2\)。
- 如果 \(a\geqslant 2b\),那么 \(a\leftarrow a-2b\),并跳回操作 \(1\),否则跳到操作 \(3\)。
- 如果 \(b\geqslant 2a\),那么 \(b\leftarrow b-2a\),并跳回操作 \(1\),否则结束操作。
求出操作结束后的 \(a,b\)。
数据范围:\(1\leqslant a,b\leqslant 10^{18}\)。
Solution
那么我们发现,如果 \(a=10^{18},b=1\) 的极限数据下,直接模拟肯定会时间爆炸的,那么怎么办?我们发现,如果满足要求,那么一个数会一直减一直减,知道这个数不满足要求为止,那么不就是取模操作吗?那么上面的 \(2,3\) 操作换成 \(a\leftarrow a\mod 2b,b\leftarrow b\mod 2a\),不就可以节省很多时间吗?
剩下的就只是判断的问题了。
Code
long long a, b;
void ans(ll a, ll b) {
if(!a || !b) {
writell(a), putchar(' '), writell(b);
return;
}
if(a >= 2 * b) ans(a % (2 * b), b);
else if(b >= 2 * a) ans(a, b % (2 * a));
else {
writell(a), putchar(' '), writell(b);
return;
}
}
int main() {
getll(a), getll(b);
ans(a, b);
return 0;
}