我当时的代码(和这个差不多,用文件输入输出,只是没用快读用的同步流),极限数据是 2s 不到一点,如果不手写 lower_bound 会超过 2s,但是 lg 神机 0.5s 就过了,所以在 ccf 机子上能不能过
#include<bits/stdc++.h>
#define ll long long
#define _for(i,a,b) for(ll i=(a);i<=(b);++i)
#define _forc(i,a,b,c) for(ll i=(a);i<=(b);++i,c)
#define _rep(i,a,b) for(ll i=(a);i>=(b);--i)
#define _repc(i,a,b,c) for(ll i=(a);i>=(b);--i,c)
#define INF 1e18
#define pl pair<ll,ll>
using namespace std;
ll read(){ll s=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}while(isdigit(c))s=s*10+c-'0',c=getchar();return s*f;}
void write(ll x){if(x<0){putchar('-');x=-x;}if(x>9)write(x/10);putchar(x%10+'0');}
void pc(){putchar(' ');}
void pn(){puts("");}
#define N 100009
ll T,n,m,L,V,d[N],v[N],a[N],p[N],nseg,ans,ans2,ra;
struct seg{ll l,r;}sg[N];
bool cmp(seg x,seg y){
return x.r<y.r;
}
ll lb(ll l1,ll r1,ll s1){
ll ans=m;
while(l1<=r1){
ll mid=(l1+r1)/2;
if(p[mid]>=s1)ans=mid,r1=mid-1;
else l1=mid+1;
}
return ans;
}
int main(){
T=read();
while(T--){
n=read(),m=read(),L=read(),V=read();
nseg=0,ans=0,ans2=0,ra=0;
_for(i,1,n)d[i]=read(),v[i]=read(),a[i]=read();
_for(i,1,m)p[i]=read();
_for(i,1,n){
if(a[i]==0){
if(v[i]>V&&d[i]<=p[m]){
ans++;
sg[++nseg].r=m;
ll u2=lb(1,m,d[i]);
sg[nseg].l=u2;
}
}
else if(a[i]>0){
ll q=2*a[i],z=V*V+2*a[i]*d[i]-v[i]*v[i];
if(q*p[m]>z&&d[i]<=p[m]){
ans++;
sg[++nseg].r=m;
auto it=lower_bound(p+1,p+1+m,d[i]);
ll u2=lb(1,m,d[i]);
ll lp=u2,rp=m,ansl=m;
while(lp<=rp){
ll mid=(lp+rp)/2;
if(q*p[mid]>z)ansl=mid,rp=mid-1;
else lp=mid+1;
}
sg[nseg].l=ansl;
}
}
else{
ll q=2*a[i],z=V*V+2*a[i]*d[i]-v[i]*v[i];
auto it=lower_bound(p+1,p+1+m,d[i]);
ll u2=lb(1,m,d[i]),u1=p[u2];
if(q*u1>z&&d[i]<=p[m]){
ans++;
sg[++nseg].l=u2;
ll lp=u2,rp=m,ansr=u2;
while(lp<=rp){
ll mid=(lp+rp)/2;
if(q*p[mid]>z)ansr=mid,lp=mid+1;
else rp=mid-1;
}
sg[nseg].r=ansr;
}
}
}
sort(sg+1,sg+1+nseg,cmp);
for(ll i=1;i<=nseg;i++){
if(ra<sg[i].l)ra=sg[i].r,ans2++;
}
cout<<ans<<" "<<m-ans2<<"\n";
}
return 0;
}