CF2145F Long Journey

你在 \(0\) 时刻位于数轴上的 \(0\) 位置。每个时刻开始时,你可以选择右移一个单位,或者停在原地。在第 \(t\) 个时刻结束时,如果你的位置 \(p\) 满足 \(p \equiv b_{t\bmod n} \pmod {a_{t\bmod n}}\),那么你就输了,注意 \(0\) 时刻可能已经满足这个条件,但是忽略这种情况。

询问到达数轴上 \(m\) 位置需要的最少时间,或报告不可能。

\[1\le n,a_i \le 10,1\le m \le 10^{12} \]


敏锐地注意到数据范围非常小。

首先一个观察是,能向前走的时候就向前走一定是最优的。

证明是,假设某一个时刻等待能够比向前走更快达到终点,

image

那么我们调整成如图的绿色路线一定不会更劣。

image

因此我们只需要贪心地向前走就可以了。

考虑加速这个过程。

发现 \(\text{LCM}(1,2,3,4,5,6,7,8,9,10)=2520\)

因此我们可以记录 \(f_{i,j,k}\),表示当前状态满足 \(t\equiv i\pmod n\)\(p\equiv j\pmod {LCM}\),经过 \(2^k\) 时间后,能走多远。

边界状态是 \(f_{i,j,0}=[j+1\not\equiv b_{(i+1)\bmod n} \pmod {a_{(i+1)\bmod n}}]\)

然后可以简单递推,查询的时候倍增即可。

#pragma GCC optimize("Ofast", "inline")
#include <algorithm>
#include <iostream>
#include <vector>
#include <tuple>

const int N = 11, M = 60, L = 2521;
#define rep(i,a,b) for(int i(a);i<=(b);++i)
#define rap(i,a,b) for(int i(a);i<(b);++i)
typedef long long i64;

i64 m;
int n;
int a[N], b[N], pow2[M];
i64 dp[M][N][L];
void solve() {
	std::cin >> n >> m; int L = 1;
	rep(i, 1, n) std::cin >> a[i], L = L * a[i] / std::__gcd(L, a[i]);
	rep(i, 1, n) std::cin >> b[i];
	a[0] = a[n], b[0] = b[n], pow2[0] = 1;
	rap(i, 1, M) pow2[i] = pow2[i-1] * 2 %n;
	rap(i, 0, n) {
		rap(j, 0, L) {
			int x = (i + 1) % n;
			dp[0][i][j] = (j + 1) % a[x] != b[x];
		}
	}
	i64 turn = 1;
	rap(k, 1, M) {
		rap(i, 0, n) {
			rap(j, 0, L) {
				int a = (i + turn) % n, b = (j + dp[k-1][i][j]) % L;
				dp[k][i][j] = dp[k-1][i][j] + dp[k-1][a][b];
			}
		}	
		turn = turn * 2 %n;
	}
	i64 last = m, ans = 0;
	int a = 0, b = 0;
	for(int i = M - 1; i >= 0; --i) {
		if(last > dp[i][a][b]) {
			last -= dp[i][a][b];
			b = (b + dp[i][a][b]) %L;
			a = (a + pow2[i]) %n;
			ans += 1ll << i;
		}
	}
	for(int i = M - 1; i >= 0; --i) {
		if(dp[i][a][b] == 0) {
			b = (b + dp[i][a][b]) %L;
			a = (a + pow2[i]) %n;
			ans += 1ll << i;
		}
	}
	if(dp[0][a][b] == 0) std::cout << "-1\n";
	else std::cout << ans+1 << "\n";
}

int main() {
	std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0);
	int t; std::cin >> t; for(; t--; ) solve();
}
posted @ 2025-10-09 10:57  CuteNess  阅读(8)  评论(0)    收藏  举报