我想的是把区间按左端点从小到大排序,如果当前区间和前面没交集就计入答案并将当前区间看作新区间,否则更新右端点。不知道对不对。
代码:(超速车辆计数应该没问题吧)
#include<bits/stdc++.h>
#define l first
#define r second
using namespace std;
typedef pair<int,int> PII;
const int N=100010,M=1000010;
int n,m,L,vm,d[N],v[N],a[N],p[N];
int lower_bound(double x){
int l=1,r=m;
while(l<r){
int mid=l+r>>1;
if(p[mid]>=x) r=mid;
else l=mid+1;
}
return r;
}
double dx(int v0,int vt,int a){
return (vt*vt-v0*v0)*1.00/(2*a);
}
bool cmp(PII a,PII b){
return a.l<b.l;
}
int main(){
int t;
cin>>t;
while(t--){
int cnt=0;
cin>>n>>m>>L>>vm;
vector<PII> p1;
for(int i=1;i<=n;i++) cin>>d[i]>>v[i]>>a[i];
for(int i=1;i<=m;i++) cin>>p[i];
for(int i=1;i<=n;i++){
if(d[i]>p[m]) continue;
int s=lower_bound((double)d[i]);
if(a[i]==0&&v[i]>vm) cnt++,p1.push_back({s,m});
else if(a[i]>0&&v[i]*v[i]+2*a[i]*(p[m]-d[i])>vm*vm) cnt++,p1.push_back({lower_bound((double)d[i]+dx(v[i],vm,a[i])),m});
else if(a[i]<0&&v[i]*v[i]+2*a[i]*(p[s]-d[i])>vm*vm) cnt++,p1.push_back({s,lower_bound((double)d[i]+dx(v[i],vm,a[i]))});
}
sort(p1.begin(),p1.end(),cmp);
int rm=-1,ans=0;
for(int i=0;i<p1.size();i++){
int l=p1[i].l,r=p1[i].r;
if(l>rm) ans++,rm=r;
else rm=min(rm,r);
}
cout<<cnt<<" "<<ans<<endl;
}
return 0;
}