rt,跑大样例T飞了,洛谷上1s不到,复杂度为O(Tnlogn)
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int t,n,m,cnt,ans,zh,ma;
double l,V,d[N],v[N],a[N],p[N];
struct CAR
{
int zuo,you;
}e[N];
bool cmp(CAR x,CAR y)
{
return x.you<y.you;
}
int er1(double x)
{
int l=1,r=m,ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(p[mid]>=x)
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
return ans;
}
int er2(double x)
{
int l=1,r=m,ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(p[mid]>x)
{
ans=mid;
r=mid-1;
}
else l=mid+1;
}
return ans;
}
int er3(double x)
{
int l=1,r=m,ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(p[mid]<x)
{
ans=mid;
l=mid+1;
}
else r=mid-1;
}
return ans;
}
int main()
{
// freopen("detect5.in","r",stdin);
// freopen("detect.out","w",stdout);
// system("fc detect.out detect5.ans");
scanf("%d",&t);
while(t--)
{
ans=cnt=zh=ma=0;
scanf("%d%d%lf%lf",&n,&m,&l,&V);
if(n>=100000) while(1);
for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&d[i],&v[i],&a[i]);
for(int i=1;i<=m;i++) scanf("%lf",&p[i]);
for(int i=1;i<=n;i++)
{
if(v[i]>V&&a[i]>=0)
{
int t=er1(d[i]);
if(!t) continue;
ans++;
ma=max(ma,t);
continue;
}
if(v[i]<=V&&a[i]<=0) continue;
double wy=d[i]+(V*V-v[i]*v[i])/(a[i]*2.0);
if(a[i]<0)
{
int ks=er3(d[i]),js=er1(wy);
if(!js) js=m+1;
int da=js-ks-1;
if(da<=0) continue;
ks++,js--;
ans++;
e[++cnt].zuo=ks;
e[cnt].you=js;
}
else
{
int hm=er2(wy);
if(!hm) continue;
ma=max(ma,hm);
ans++;
}
}
sort(e+1,e+cnt+1,cmp);
// for(int i=1;i<=cnt;i++) cout<<e[i].zuo<<" "<<e[i].you<<"\n";
int zz=1,zdz=0,dq;
while(zz<=cnt)
{
dq=e[zz].you;
zdz=max(zdz,zz);
zh++;
for(int i=zz+1;i<=cnt;i++)
{
if(e[i].zuo<=dq&&e[i].you>=dq) zz=i;
else break;
}
zz++;
}
if(e[zdz].you<ma) zh++;
printf("%d %d\n",ans,m-zh);
}
return 0;
}