rt,大致思路跟 chen_zhe 的 std 一样,但是我二分写法不太一样。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 1e5 + 10;
int T, n, m, ans1, ans2, cnt;
struct Car{
ll d, v, a;
}c[N];
ll p[N], L, V;
struct node{
int l, r;
bool operator<(const node & B) const{
if(r == B.r) return l < B.l;
return r < B.r;
}
}s[N];
int myfid1(int l, int r, int i){ //找第一个合格的
int mid;
while(l < r){
mid = (l + r) >> 1;
if(c[i].v * c[i].v + 2ll * c[i].a * (p[mid] - c[i].d) > V * V){
r = mid;
}
else l = mid + 1;
}
return r;
}
int myfid2(int l, int r, int i){ //找最后一个不合格的
int mid;
while(l < r){
mid = (l + r) >> 1;
if(c[i].v * c[i].v + 2ll * c[i].a * (p[mid] - c[i].d) > V * V){
l = mid + 1;
}
else r = mid;
}
return r;
}
int main(){
//freopen("D:\\OIproblem\\detect\\detect5.in", "r", stdin);
//freopen("D:\\OIproblem\\detect\\myans.ans", "w", stdout);
scanf("%d", &T);
while(T--){
scanf("%d%d%lld%lld", &n, &m, &L, &V);
for(int i = 1; i <= n; i++){
scanf("%lld%lld%lld", &c[i].d, &c[i].v, &c[i].a);
}
for(int i = 1; i <= m; i++){
scanf("%lld", &p[i]);
}
ans1 = ans2 = cnt = 0;
for(int i = 1; i <= n; i++){
int id = lower_bound(p + 1, p + m + 1, c[i].d) - p;
if(id == m + 1) continue;
if(c[i].a >= 0){
if(c[i].v * c[i].v + 2ll * c[i].a * (p[m] - c[i].d) > V * V){
++ans1;
int id2 = myfid1(id, m, i);
s[++cnt] = (node){id2, m};
}
}
else{
if(c[i].v * c[i].v + 2ll * c[i].a * (p[id] - c[i].d) > V * V){
++ans1;
int id2 = myfid2(id, m, i);
s[++cnt] = (node){id, id2 - 1};
}
}
}
sort(s + 1, s + cnt + 1);
//统计答案
int lst = 0;
for(int i = 1; i <= cnt; i++){
if(s[i].l > lst){
++ans2;
lst = s[i].r;
}
}
printf("%d %d\n", ans1, m - ans2);
}
return 0;
}
说句闲话
本人场上对了出 #2 样例的一组数据以外的所有样例,然后气急败坏写了如下注释:
I cannot accept #2
but I can accept #1,3,4,5
Why 9 7?
how about 5 8?
应该不会被禁三吧