P1728 [PA 2014] Parking

P1728\(\mathbf{} \begin{Bmatrix} \frac{{\Large LUOGU-P1728} }{{\color{Red}\Large Solution} }\mathbf{} {No.10} \end{Bmatrix}\times{}\) NeeDna

非常有意思的一道题!

题目分析:发现车子之间会相互移动,高度有限但宽度无限。类似一条线。接着对于一个车思考,它会穿过一些车,到达另一侧,而且只有需要穿过的车可能不满足要求,思路较为清楚了。现在思考一个车具体需要穿过(或被穿过)的车,就是开始在他前面,但结尾在他后面的车。

思路有了,所以先读入,然后排序,然后处理,发现与要处理单点修改和区间查询最大值,用树状数组即可。

判断逻辑:

for(int i=n;i>=1;i--){
	if(sc(a[e[i].id])+abs(e[i].Y-e[i].y)>w){
		cout<<"NIE\n";f=0;break;
	}
	upd(a[e[i].id],abs(e[i].Y-e[i].y));
}if(f) cout<<"TAK\n";

AC code:

#include<bits/stdc++.h>
#define lowbit(x) (x&(-x))
using namespace std;
const int N=5e4+10;
int T,n,w,a[N],tr[N];
struct Car{
	int id,x,y,X,Y;
}s[N],e[N];
int sc(int x){int ans=0;while(x>0){ans=max(tr[x],ans);x-=lowbit(x);}return ans;}
void upd(int x,int k){while(x<=n){tr[x]=max(tr[x],k);x+=lowbit(x);}}
bool c(Car a,Car b){return a.x<b.x;}
void init(Car s[]){
	for(int i=1;i<=n;++i){
		int x,y,X,Y;
		cin>>x>>y>>X>>Y;
		if(x>X)swap(x,X),swap(y,Y);
		s[i]={i,x,y,X,Y};
	}
}
int main(){
	std::ios::sync_with_stdio(false);
	cin>>T;
	while(T--){
		memset(tr,0,sizeof(tr));
		cin>>n>>w;int f=1;
		init(s);init(e);
		sort(s+1,s+1+n,c);sort(e+1,e+1+n,c);
		for(int i=1;i<=n;++i)a[s[i].id]=i;
		for(int i=n;i>=1;i--){
			if(sc(a[e[i].id])+abs(e[i].Y-e[i].y)>w){
				cout<<"NIE\n";f=0;break;
			}
			upd(a[e[i].id],abs(e[i].Y-e[i].y));
		}if(f) cout<<"TAK\n";
	}
	
	return 0;
} 
posted @ 2025-05-30 20:51  NeeDna  阅读(6)  评论(0)    收藏  举报