捞,由于改用差分约束处理点覆盖时答案正确(只是超时),所以初步认为问题出在这步上。但好像还是没有从中发现问题 /kk
#include <bits/stdc++.h>
using namespace std;
int T, n, m, L, V, d[100001], v[100001], a[100001], p[100001];
struct interval {
int l, r;
bool operator<(const interval &x) const {
return l < x.l;
}
} t[100001];
int findl(int i, int l, int r) {
while (l <= r) {
int mid = (l + r) >> 1;
if ((p[mid] - d[i]) * a[i] * 2 > V * V - v[i] * v[i]) r = mid - 1;
else l = mid + 1;
}
return l;
}
int findr(int i, int l, int r) {
while (l <= r) {
int mid = (l + r) >> 1;
if ((p[mid] - d[i]) * a[i] * 2 <= V * V - v[i] * v[i]) r = mid - 1;
else l = mid + 1;
}
return r;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("detect.in", "r", stdin);
freopen("detect.out", "w", stdout);
#endif
scanf("%d", &T);
while (T--) {
scanf("%d%d%d%d", &n, &m, &L, &V);
for (int i = 1; i <= n; i++) scanf("%d%d%d", &d[i], &v[i], &a[i]);
for (int i = 1; i <= m; i++) scanf("%d", &p[i]);
int cnt = 0, ans1 = 0, ans2 = 1;
for (int i = 1; i <= n; i++) {
int pos = lower_bound(p + 1, p + m + 1, d[i]) - p;
if (pos > m) continue;
if (v[i] > V && a[i] >= 0) {
t[++cnt] = (interval){pos, m};
ans1++;
}
else if (v[i] <= V && a[i] > 0) {
int l = findl(i, pos, m);
if (l <= m) {
t[++cnt] = (interval){l, m};
ans1++;
}
}
else if (v[i] > V && a[i] < 0) {
int r = findr(i, pos, m);
if (pos <= r) {
t[++cnt] = (interval){pos, r};
ans1++;
}
}
}
sort(t + 1, t + cnt + 1);
for (int i = 2, R = t[1].r; i <= cnt; i++) {
if (t[i].l > R) {
R = t[i].r;
ans2++;
}
else R = min(R, t[i].r);
}
printf("%d %d\n", ans1, m - ans2);
}
return 0;
}