基本信息
题解
设 ,显然每 秒的按键情况都是一样的。 秒内 BaoBao 将会按键 次(每次按 下),DreamGrid 将会按键 次(每次按 下),因此直接模拟的复杂度是 。
- 若 ,直接模拟每次按键。
- 若 ,通过直接模拟,计算 这个时间段计数器增加的数值 ,以及第 秒开始时 LED 是否还亮着(如果亮着,记 ,否则记 )。之后再通过直接模拟,算出最后 秒计数器增加的数值 ,则答案为 。
复杂度仍然为 。
参考代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 | #include <bits/stdc++.h>
using namespace std;
typedef pair<long long, bool> plb;
int a, b, c, d;
long long v, t;
// 直接模拟按键情况,
// 返回 [0, t] 这个时间段计数器增加的数值,
// 以及第 (t + 1) 秒开始时 LED 是否亮着
plb gao(long long t) {
// cnt:计数器的值
// tim:LED 最后亮到哪一秒
long long cnt = 0, tim = -1;
// now:现在的时间
// x:BaoBao 下一次按键的时间
// y:DreamGrid 下一次按键的时间
long long now = 0, x = 0, y = 0;
while (now <= t) {
// BaoBao 按键
if (now == x) {
cnt += b - (now > tim ? 1 : 0);
tim = now + v;
x += a;
}
// DreamGrid 按键
if (now == y) {
cnt += d - (now > tim ? 1 : 0);
tim = now + v;
y += c;
}
// 前进到下一个按键的时刻
now = min(x, y);
}
return plb(cnt, tim > t);
}
void solve() {
scanf("%d%d%d%d%lld%lld", &a, &b, &c, &d, &v, &t);
long long l = 1LL * a / gcd(a, c) * c;
if (t < l) printf("%lld\n", gao(t).first);
else {
plb p1 = gao(l - 1);
plb p2 = gao(t % l);
printf("%lld\n", (p1.first + (p1.second ? 1 : 0)) * (t / l) + p2.first);
}
}
int main() {
int tcase; scanf("%d", &tcase);
while (tcase--) solve();
return 0;
}
|