调了3h彻底泪崩WA0pts*8需要安慰
查看原帖
调了3h彻底泪崩WA0pts*8需要安慰
941560
HeiCat0725楼主2024/11/2 11:31

二分+贪心,只能过样例1和2,样例3区间选点选出来错误,样例4和5没一个数据是对的。从早上八点干到十一点半,中途只休息了10分钟。

非常好题目,使我的100+行代码旋转。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=1e5+5;
int n,m,L,v;
struct node{
	int d,v0,a;
}arr[N];
struct lrnode{
	int l,r;
}dp[N];
int drr[N];

bool cmp1(lrnode a,lrnode b){return a.r<b.r;}
int upbs(int i,int b){//加速在哪里大于v (或无解)
	int l=b,r=m,res=-1;
	while(l<=r){
		int mid=(l+r)>>1;
		if((drr[mid]-arr[i].d)*2*arr[i].a+arr[i].v0*arr[i].v0>v*v){
			r=mid-1;
			res=mid;
		}else l=mid+1;
	}
	return res;
}
int downbs(int i,int b){//减速在哪里最后大于v? 
	int l=b,r=m,res=-1;
	while(l<=r){
		int mid=(l+r)>>1;
		if((drr[mid]-arr[i].d)*2*arr[i].a+arr[i].v0*arr[i].v0>v*v){
			l=mid+1;
			res=mid;
		}else r=mid-1;
	}
	return res;
}

void sovled(){
	int ans=0,ans2=0;
	memset(arr,0,sizeof(arr));
	memset(dp,0,sizeof(dp));
	memset(drr,0,sizeof(drr));
	
	scanf("%d%d%d%d",&n,&m,&L,&v);
	for(int i=1;i<=n;i++) scanf("%d%d%d",&arr[i].d,&arr[i].v0,&arr[i].a);
	for(int i=1;i<=m;i++) scanf("%d",&drr[i]);
	sort(drr+1,drr+m+1);
	for(int i=1;i<=n;i++){
		int v0=arr[i].v0,d=arr[i].d;
		if(d>drr[m]){
			dp[i].l=dp[i].r=-1;
			continue;
		}
		int b=lower_bound(drr+1,drr+n+1,d)-drr;
	//	cout<<b<<",\n";
		if(arr[i].a>0){
			if(v0>v) dp[i].l=b,dp[i].r=m,ans++;
			else{
				int c=upbs(i,b);
				if(c==-1) dp[i].l=dp[i].r=-1;
				else{
					dp[i].l=c,dp[i].r=m;
					ans++;
				} 
			}
		}else if(arr[i].a==0){
			if(v0>v) dp[i].l=b,dp[i].r=m,ans++;
			else dp[i].l=dp[i].r=-1;
		}else{
			if(v0>v){
				int c=downbs(i,b);
				if(c==-1) dp[i].l=dp[i].r=-1;
				else{//
					dp[i].l=b,dp[i].r=c;
					ans++;
				}
			}else dp[i].l=dp[i].r=-1;
		}
	//	printf("%d %d\n",dp[i].l,dp[i].r);
	}
	printf("%d ",ans);
	if(ans==0){
		printf("%d\n",m);
		return ;
	}
	sort(dp+1,dp+n+1,cmp1);
	int rnow=1;
	for(;rnow<=n;rnow++){
		if(dp[rnow].r!=-1){
			break;
		}
	}
	if(rnow<=n) ans2++;
	for(int i=rnow+1;i<=n;i++){
		if(dp[i].l>dp[rnow].r){
			rnow=i;
			ans2++;
		}
	}
	printf("%d\n",m-ans2);
	return ;
}
int main(){
	//freopen("detect3.in","r",stdin); 
	//freopen("detect3.out","w",stdout); 
	int t;
	scanf("%d",&t);
	while(t--){
		sovled();
	}
	return 0;
}
/*
**超过**道路限速 V  完啦! =(
*/
2024/11/2 11:31
加载中...