rt, 本地已经通过了全部大样例, 但是在 大样例 & Hack 自测 中寄了
#include <bits/stdc++.h>
const int MAXN = 1e5 + 20;
int T;
int n, m, L, V;
struct node
{
int d, v, a;
int Left, Right;
} Car[MAXN];
int p[MAXN];
void Calc(int Now)
{
if (Car[Now].v > V)
{
if (Car[Now].a >= 0)
{
Car[Now].Left = Car[Now].d, Car[Now].Right = L;
return;
}
else
{
Car[Now].Left = Car[Now].d;
Car[Now].Right = (int)(std::min(double(L), double(Car[Now].d) + (double)((V * V) - (Car[Now].v * Car[Now].v)) / (2 * Car[Now].a)));
if (((V * V) - (Car[Now].v * Car[Now].v)) % (2 * Car[Now].a) == 0)
{
Car[Now].Right--;
}
return;
}
}
else
{
if (Car[Now].a > 0)
{
Car[Now].Left = ((int)(double(Car[Now].d) + (double)((V * V) - (Car[Now].v * Car[Now].v)) / (2 * Car[Now].a)) > L) ? 0 : (int)(double(Car[Now].d) + (double)((V * V) - (Car[Now].v * Car[Now].v)) / (2 * Car[Now].a));
if (((V * V) - (Car[Now].v * Car[Now].v)) % (2 * Car[Now].a) == 0 && Car[Now].Left != 0)
{
Car[Now].Left++;
}
Car[Now].Right = (Car[Now].Left == 0) ? 0 : L;
return;
}
else
{
Car[Now].Left = 0, Car[Now].Right = 0;
return;
}
}
}
bool CanBeDetected[MAXN];
class Detect
{
private:
/*0 符合要求; 1 偏左; 2 偏右*/
int check(int x, int Now)
{
if (p[x] >= Car[Now].Left && p[x] <= Car[Now].Right)
{
return 0;
}
else if (p[x] < Car[Now].Left)
{
return 1;
}
else
{
return 2;
}
}
public:
bool Bin_Search(int Now)
{
int Left = 1, Right = m;
CanBeDetected[Now] = false;
while (Left <= Right)
{
int Mid = (Left + Right) >> 1;
int Type = check(Mid, Now);
if (Type == 0)
{
CanBeDetected[Now] = true;
return CanBeDetected[Now];
}
else
{
if (Type == 1)
{
Left = Mid + 1;
}
else
{
Right = Mid - 1;
}
}
}
}
void solve()
{
for (int i = 1; i <= n; i++)
{
Bin_Search(i);
}
}
} detect;
int MustUse = 0;
class Solution
{
private:
bool check(int Pos, int x)
{
if (p[x] >= Pos)
return true;
else
return false;
}
int Bin_Search(int Pos)
{
int Left = 1, Right = m;
int Ans = 0;
while (Left <= Right)
{
int Mid = (Left + Right) >> 1;
if (check(Pos, Mid))
{
Ans = Mid;
Right = Mid - 1;
}
else
{
Left = Mid + 1;
}
}
return Ans;
}
struct Range
{
int Left, Right;
friend bool operator<(Range a, Range b)
{
return a.Left < b.Left;
}
} Ran[MAXN];
int cnt;
public:
void solve()
{
cnt = 0, MustUse = 0;
for (int i = 1; i <= n; i++)
{
if (CanBeDetected[i])
Ran[++cnt].Left = Car[i].Left, Ran[cnt].Right = Car[i].Right;
}
std::sort(Ran + 1, Ran + cnt + 1);
/*倒序扫描*/
int Min_P = -1;
for (int i = cnt; i >= 1; i--)
{
if (Min_P == -1 || (p[Min_P] < Ran[i].Left || p[Min_P] > Ran[i].Right))
{
MustUse++;
Min_P = Bin_Search(Ran[i].Left);
}
}
printf("%d %d\n", cnt, m - MustUse);
}
} Sol;
int main()
{
// freopen("detect5.in", "r", stdin);
// freopen("detect.out", "w", stdout);
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", &Car[i].d, &Car[i].v, &Car[i].a);
Calc(i);
}
for (int i = 1; i <= m; i++)
{
scanf("%d", &p[i]);
}
/*计算有多少个区间会被检测到 O(NlogM)*/
detect.solve();
/*贪心处理*/
Sol.solve();
}
return 0;
}
/*
1
5 5 15 3
0 3 0
12 4 0
1 1 4
5 5 -2
6 4 -4
2 5 8 9 15
3 3
*/