题意
传送门 AtCoder ABC 319E Bus Stops
题解
对于停车点间的每一段距离,仅跟抵达前驱车站模 P i P_i Pi 的模数相关。考虑中国剩余定理 x m o d n ↔ ( x m o d a , x m o d b ) , n = a ⋅ b , g c d ( a , b ) = 1 x\mod n \leftrightarrow (x\mod a, x\mod b),n=a\cdot b,gcd(a,b)=1 xmodn↔(xmoda,xmodb),n=a⋅b,gcd(a,b)=1。题目中的 P i P_i Pi 虽然不一定互素,但转化的思想基本一致,即:令 M = l c m ( 1 , 2 , ⋯ , 8 ) M=lcm(1,2,\cdots,8) M=lcm(1,2,⋯,8), x m o d M → ( x m o d 1 , ⋯ , x m o d 8 ) x\mod M\rightarrow (x\mod 1, \cdots, x\mod 8) xmodM→(xmod1,⋯,xmod8),同时考虑线性同余方程组的求解,相反方向的推论也成立。那么预处理出 0 , 1 , ⋯ M 0,1,\cdots M 0,1,⋯M 的答案,再加上 ⌊ q / M ⌋ ⋅ M \lfloor q/M\rfloor \cdot M ⌊q/M⌋⋅M 即可。总时间复杂度 O ( M N + Q ) O(MN+Q) O(MN+Q)。
#include <bits/stdc++.h>
using namespace std;
constexpr int MOD = 840;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, x, y;
cin >> n >> x >> y;
n -= 1;
vector<int> p(n), t(n);
for (int i = 0; i < n; ++i) {
cin >> p[i] >> t[i];
}
using ll = long long;
auto get = [&](int bg) {
ll v = bg + x;
for (int i = 0; i < n; ++i) {
int m = v % p[i];
if(m > 0) {
v += p[i] - m;
}
v += t[i];
}
v += y;
return v;
};
vector<ll> mem(MOD);
for (int i = 0; i < MOD; ++i) {
mem[i] = get(i);
}
int q;
cin >> q;
while (q--) {
int k;
cin >> k;
ll res = k / MOD * MOD + mem[k % MOD];
cout << res << '\n';
}
return 0;
}