社区讨论

样例全过,80pts,WA两个点,求调

P11232[CSP-S 2024] 超速检测参与者 5已保存回复 10

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
10 条
当前快照
1 份
快照标识符
@mhj1uli0
此快照首次捕获于
2025/11/03 19:21
4 个月前
此快照最后确认于
2025/11/03 19:21
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
long long T,n,m,L,V,p[100010],s[1000010],t,x,y;
struct node
{
	long long d,v,a;
}a[100010];
struct pr
{
	long long l,r;
}b[100010],c[100010];
double avt(double V0,double aa,double tt) {return (V0*tt)+(double(aa)*tt/2.0*tt);}//已知V0、a、t 求S; 
void work(long long i)//车辆i是否超速 
{
	if(a[i].v>V)
	{
		x=a[i].d;
		if(a[i].a>=0) y=L;
		else 
		{
			double temp,cnt;
			temp=(double)(V-a[i].v)*1.0/a[i].a;
			cnt=avt(a[i].v,a[i].a,temp)+a[i].d;
			y=min(L,(long long)(cnt));
		}
	}
	else
	{
		if(a[i].a<=0) return ;
		double temp,cnt;
		temp=(double)(V-a[i].v)*1.0/a[i].a;
		cnt=avt(a[i].v,a[i].a,temp)+a[i].d;
		if(cnt>L) return ;
		x=(long long)(cnt)+1;
		y=L;
	}
	if((x==0&&s[y])>0||s[y]-s[x-1]>0)
	{
		b[++t].l=x;
		b[t].r=y;
	} 
}
bool cmp(pr xx,pr yy)
{
	if(xx.l!=yy.l) return xx.l<yy.l;
	return xx.r>yy.r;
}
void qc()
{
	t=0;
	for(int i=1;i<=n;i++)
	{
		int j=i,l=b[i].l,r=b[i].r;
		while(l<=b[j+1].l&&b[j+1].r<=r&&j+1<=n) 
		{
			l=b[j+1].l;r=b[j+1].r;j++;
		}
		while(c[t].l<=b[j].l&&b[j].r<=c[t].r&&t>0)
		{
			t--;
		}
		c[++t]=b[j];
		i=j;
	}
}
int f(int le,int ri)
{
	int l=1,r=m,mid,ans=-1;
	while(l<=r)
	{
		mid=(l+r)>>1;
		if(p[mid]<=ri)
		{
			ans=mid;
			l=mid+1;
		}
		else
		{
			r=mid-1;
		}
	}
	return ans;
}
int main()
{
	cin>>T;
	while(T--)
	{
		t=0;
		scanf("%lld %lld %lld %lld",&n,&m,&L,&V);
		for(long long i=1;i<=n;i++) 
		{
			scanf("%lld %lld %lld",&a[i].d,&a[i].v,&a[i].a);
		}
		memset(s,0,sizeof(s));
		memset(b,0,sizeof(b));
		memset(c,0,sizeof(c));
		for(long long i=1;i<=m;i++) {scanf("%lld",&p[i]),s[p[i]]++;}
		for(long long i=1;i<=L;i++) s[i]+=s[i-1];
		s[L+1]=-2e9;
		for(long long i=1;i<=n;i++) work(i);
		n=t;
		sort(b+1,b+n+1,cmp);
		if(n==0)
		{
			cout<<0<<' '<<m<<endl;
			continue;
		}
		qc();
		long long ans=0;
		for(long long i=1;i<=t;i++)
		{
			x=f(c[i].l,c[i].r);
			while(c[i+1].l<=p[x]&&p[x]<=c[i+1].r&&i+1<=t) i++;
			ans++;
		}
		cout<<n<<' '<<(m-ans)<<endl;
	}

	return 0;
}
第一个问题用的前缀和,第二个是先去重再二分、贪心,大数据对拍两个问题都有小概率出错,小数据没拍出来

回复

10 条回复,欢迎继续交流。

正在加载回复...