洛谷 P11232 [CSP-S 2024] 超速检测
首先可以对每一辆车计算出能检测出其超速的区间。分析之后发现直接对着这些区间考虑是不太好做的(考场上卡在这里了)。所以考虑二分得到每辆车能被哪些测速仪测出超速,于是每辆车都对应一个测速仪的位置区间。
将这些区间按右端点升序排序,可以贪心地用区间的右端点考虑:如果右端点不在下一个区间内,说明需要新开一个测速仪测下一个区间对应车辆的速度。时间复杂度 \(\mathcal{O}(n\log n)\)。
点击查看代码
#include<bits/stdc++.h>
using namespace std;
bool Mbegin;
void File_Work(){
freopen("detect.in","r",stdin);
freopen("detect.out","w",stdout);
}
const int N=1e5+8;
int n,m,L,V,p[N],d[N],v[N],a[N];
struct Interval{
int l,r;
void init(){
l=r=0;
}
friend bool operator <(Interval a,Interval b){
if(a.r!=b.r)
return a.r<b.r;
return a.l<b.l;
}
}itv[N];
bool check(int pos,int i){
int x=p[pos]-d[i];
int v2=v[i]*v[i]+2*a[i]*x;
if(V*V<v2)
return 1;
return 0;
}
void MAIN(){
for(int i=1;i<=n;i++)
p[i]=0,itv[i].init();
cin>>n>>m>>L>>V;
for(int i=1;i<=n;i++)
cin>>d[i]>>v[i]>>a[i];
for(int i=1;i<=m;i++)
cin>>p[i];
sort(p+1,p+m+1);
int ans1=0;
for(int i=1;i<=n;i++){
if(p[m]<d[i])
continue;
int pos=lower_bound(p+1,p+m+1,d[i])-p;
if(a[i]==0&&v[i]>V)
itv[++ans1]={pos,m};
else if(a[i]<0){
int x=p[pos]-d[i];
int v2=v[i]*v[i]+2*a[i]*x;
if(V*V<v2){
int l=pos,r=m,res=0;
while(l<=r){
int mid=(l+r)/2;
if(check(mid,i)==1){
res=mid;
l=mid+1;
}
else
r=mid-1;
}
itv[++ans1]={pos,res};
}
}
else if(a[i]>0){
int x=p[m]-d[i];
int v2=v[i]*v[i]+2*a[i]*x;
if(V*V<v2){
int l=pos,r=m,res=0;
while(l<=r){
int mid=(l+r)/2;
if(check(mid,i)==1){
res=mid;
r=mid-1;
}
else
l=mid+1;
}
itv[++ans1]={res,m};
}
}
}
cout<<ans1<<' ';
sort(itv+1,itv+ans1+1);
int ans2=0,cur;
for(int i=1;i<=ans1;i++){
if(itv[i].l<=cur&&cur<=itv[i].r)
continue;
ans2++;
cur=itv[i].r;
}
cout<<m-ans2<<'\n';
}
bool Mend;
int main(){
// File_Work();
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cerr<<fixed<<setprecision(3)<<(&Mbegin-&Mend)/1048576.0<<" MB\n\n\n";
int testid=0,testnum=1;
// cin>>testid;
cin>>testnum;
while(testnum--)
MAIN();
cerr<<"\n\n\n"<<fixed<<setprecision(0)<<1e3*clock()/CLOCKS_PER_SEC<<" ms";
return 0;
}