思路为二分+树状数组优化贪心。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,l,vc;
int d[100010],v[100010],a[100010];
int p[100010],t[100010],c[100010];
pair<int,int>rp[100010];
int b[100010];
inline int lowbit(int x){
return x&-x;
}
inline void update(int x,int v){
while(x<=m) b[x]+=v,x+=lowbit(x);
}
inline int ask(int x){
int ans=0;
while(x) ans+=b[x],x-=lowbit(x);
return ans;
}
inline void solve(){
cin>>n>>m>>l>>vc;
for(int i=1;i<=n;i++) cin>>d[i]>>v[i]>>a[i];
for(int i=1;i<=m;i++) cin>>p[i];
int cnt=0;
for(int i=1;i<=n;i++){
int ans=lower_bound(p+1,p+m+1,d[i])-p-1;
int TU=ans+1;
t[i]=TU;
if(a[i]<0){
for(int j=25;j>=0;j--){
if(ans+(1<<j)>m) continue;
int T=ans+(1<<j);
if(v[i]*v[i]+2*a[i]*(p[T]-d[i])>vc*vc) ans+=(1<<j);
}
c[i]=ans;
}
else if(a[i]>0){
for(int j=25;j>=0;j--){
if(ans+(1<<j)>m) continue;
int T=ans+(1<<j);
if(v[i]*v[i]+2*a[i]*(p[T]-d[i])<=vc*vc) ans+=(1<<j);
}
c[i]=ans+1;
}
else if(a[i]==0) if(v[i]>vc) c[i]=m;else c[i]=ans;
if(t[i]<=c[i] && c[i]<=m) cnt++;
}
int tot=0;
for(int i=1;i<=n;i++)
if(t[i]<=c[i] && c[i]<=m)
if(a[i]<=0) rp[++tot]={c[i],t[i]};
else rp[++tot]={m,c[i]};
sort(rp+1,rp+tot+1);
memset(b,0,sizeof b);
for(int i=1;i<=tot;i++) swap(rp[i].first,rp[i].second);
int USE__=0;
for(int i=1;i<=tot;i++){
if(ask(rp[i].second)-ask(rp[i].first-1)>0) continue;
update(rp[i].second,1),USE__++;
}
cout<<cnt<<" "<<m-USE__<<"\n";
}
signed main() {
ios::sync_with_stdio(0);
// freopen("detect5.in","r",stdin);
// freopen("detect.out","w",stdout);
int t;
cin>>t;
while(t--) solve();
return 0;
}
自己过了大样例,结果 20 pts,吓死我了。
又发现冥间数据暂时有误,所以只好到这问了。
我的照着考场思路打的