全程整数操作,没用到浮点数
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 1e5 + 9;
const long double eps = -1e-9;
int n, m, l, V, d[maxn], v[maxn], a[maxn], p[maxn], ed, ans1, ans2;
vector<pair<int, int>> dat;
inline int read()
{
int x = 0, f = 1;
char c;
for (c = getchar(); c < '0' || c > '9'; c = getchar())
if (c == '-')
f = -f;
for (; c >= '0' && c <= '9'; c = getchar())
x = (x << 3) + (x << 1) + (c ^ 48);
return x * f;
}
signed main()
{
static int T = -1;
if (T == -1)
/*freopen("dat.in", "r", stdin), freopen("code.out", "w", stdout),*/ T = read();
if (T-- == 0)
return 0;
ed = -1, dat.clear(), ans1 = 0, ans2 = 0;
n = read(), m = read(), l = read(), V = read();
for (int i = 1; i <= n; i++)
d[i] = read(), v[i] = read(), a[i] = read();
for (int i = 1; i <= m; i++)
p[i] = read();
for (int i = 1; i <= n; i++)
{
if (d[i] > p[m] || (a[i] <= 0 && v[i] <= V)) // 不可能超速或就算超速也不存在摄像头可以拍到
continue;
if (a[i] == 0) // 匀速直线运动且确定超速
ans1++, dat.emplace_back(make_pair(lower_bound(p + 1, p + m + 1, d[i]) - p, m)); // 在这个区间的所有摄像头都会拍到超速
else if (a[i] > 0)
{
// 匀加速运动
// const int mv = ceil((V * V - v[i] * v[i]) / (2.0 * a[i]) - eps); // 速度达到 V 时的位移(向上取整,因为超速当且仅当完全超过了限速 V)
const int mv = (V * V - v[i] * v[i]) / (2 * a[i]) + bool(((V * V - v[i] * v[i]) % (2 * a[i])) > 0);
if (d[i] + mv > p[m])
continue;
const int k = lower_bound(p + 1, p + m + 1, d[i] + mv) - p; // 从第 k 个摄像头可以拍到超速
ans1++, dat.emplace_back(make_pair(k, m)); // 在这个区间的所有摄像头都会拍到超速
}
else if (a[i] < 0)
{
// 匀减速运动
// const int mv = floor((V * V - v[i] * v[i]) / (2.0 * a[i]) + eps); // 速度达到 V 时的位移(向下取整,因为超速当且仅当完全超过了限速 V)
const int mv = (V * V - v[i] * v[i]) / (2 * a[i]);
int k = lower_bound(p + 1, p + m + 1, d[i]) - p, kk = lower_bound(p + 1, p + m + 1, d[i] + mv) - p; // 第 k 个到第 kk 个摄像头可以拍到超速
while (p[kk] > d[i] + mv) // 完全超过限速 V 才行
kk--;
if (kk < k)
continue;
ans1++, dat.emplace_back(make_pair(k, kk)); // 在这个区间的所有摄像头都会拍到超速
}
}
sort(dat.begin(), dat.end(), [](const auto &a, const auto &b)
{ return /*a.second == b.second ? a.first < b.first : */a.second < b.second; });
for (const auto &[l, r] : dat)
if (l > ed)
ed = r, ans2++;
printf("%lld %lld\n", ans1, m - ans2);
main();
}
我看好几个帖子都说卡精度,所有有用lower_bound过的大佬吗?