ICPC 2019 World Finals A. Azulejos

题目链接
想法是很自然的,首先对于每排能确定的地方(没有与之相等的价值)先确定,然后对每个位置,如果前后排只有一个确定了,那么另一排必然取满足条件最优的。

所以剩下一些两排都没有确定的区间,对于每个这样的区间,从左往右扫,取目前选择较少的那排为准,剩下一排取满足条件的最优,用set维护这个取的过程即可。

其实第一段的过程可以省去,因为确定的地方可以看做只有一个选择的地方,但按照原本这样想可能更自然一点。

错误点:
set在erase掉一个指针所指的set的元素的时候,这个指针就失效了(因为其所指的元素不在set内了,就会发生错误),所以在erase前要把所有用到erase的操作都完成!!!

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
struct node{
	int p,h,d;
	bool f;
	int st;
	bool operator < (const node& r) const{
		return h<r.h;
	}
}p[N],q[N];
int ts,tt;
bool cmp(node x,node y){
	return x.p<y.p;
}
struct stsz{
	multiset<node>st;
	int sz;
};
stsz s[N],t[N];
int n,a[N],b[N];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++) scanf("%d",&p[i].p),p[i].d=i;
	for(int i=1;i<=n;i++) scanf("%d",&p[i].h);
	for(int i=1;i<=n;i++) scanf("%d",&q[i].p),q[i].d=i;
	for(int i=1;i<=n;i++) scanf("%d",&q[i].h);
	sort(p+1,p+n+1,cmp);
	sort(q+1,q+n+1,cmp);
	for(int i=1;i<=n;i++){
		if(i>1 && p[i].p==p[i-1].p){
			if(!p[i-1].f) p[i-1].f=1,p[i-1].st=++ts,s[ts].st.insert(p[i-1]),s[ts].sz++;
			p[i].st=p[i-1].st;
			s[p[i].st].st.insert(p[i]);
			s[p[i].st].sz++;
			p[i].f=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(i>1 && q[i].p==q[i-1].p){
			if(!q[i-1].f) q[i-1].f=1,q[i-1].st=++tt,t[tt].st.insert(q[i-1]),t[tt].sz++;
			q[i].st=q[i-1].st;
			t[q[i].st].st.insert(q[i]);
			t[q[i].st].sz++;
			q[i].f=1;
		}
	}
	for(int i=1;i<=n;i++){
		if(!p[i].f && !q[i].f && p[i].h<=q[i].h){
			puts("impossible");
			return 0;
		}
		if(p[i].f && !q[i].f){
			multiset<node>:: iterator it=s[p[i].st].st.upper_bound(q[i]);
			if(s[p[i].st].st.empty()){
					puts("impossible");
				return 0;
			}
			if(it==s[p[i].st].st.end()){
				puts("impossible");
				return 0;
			}
			p[i]=(*it); p[i].f=0;
			s[p[i].st].st.erase(it);
			//!!!when you erase [it], you can not use it any more, so erase [it] when all finished!!!
			s[p[i].st].sz--;
		}
		if(q[i].f && !p[i].f){
			multiset<node>:: iterator it=t[q[i].st].st.lower_bound(p[i]);
			if(t[q[i].st].st.empty()){
					puts("impossible");
				return 0;
			}
			if(it==t[q[i].st].st.begin()){
				puts("impossible");
				return 0;
			}
			it--;
			q[i]=(*it); q[i].f=0;
			t[q[i].st].st.erase(it);
			t[q[i].st].sz--;
		}
	}
	int l=1,r=1,sp=0,tq=0;
	while(l<=n){
		if(!p[l].f){
			l++;
			continue;
		}
		r=l;
		while(r<n && p[r+1].f) r++;
		for(int i=l;i<=r;i++){
			sp=p[i].st;
			tq=q[i].st;
			if(s[sp].sz>=t[tq].sz){
				if(t[tq].st.empty()){
					puts("impossible");
					return 0;
				}
				multiset<node>:: iterator it=t[tq].st.begin();
				node u=(*it);
				q[i]=u;
				t[tq].st.erase(it);
				t[tq].sz--;
				if(s[sp].st.empty()){
					puts("impossible");
					return 0;
				}
				it=s[sp].st.upper_bound(u);
				if(it==s[sp].st.end()){
					puts("impossible");
					return 0;
				}
				p[i]=(*it);
				s[sp].st.erase(it);
				s[sp].sz--;
			}
			else {
				if(s[sp].st.empty()){
					puts("impossible");
					return 0;
				}
				multiset<node>:: iterator it=s[sp].st.begin();
				node u=(*it);
				p[i]=u;
				s[sp].st.erase(it);
				s[sp].sz--;
				it=t[tq].st.lower_bound(u);
				if(t[tq].st.empty()){
					puts("impossible");
					return 0;
				}
				if(it==t[tq].st.begin()){
					puts("impossible");
					return 0;
				}
				it--;
				q[i]=(*it);
				t[tq].st.erase(it);
				t[tq].sz--;
			}
		}
		l=r+1;
	}
	for(int i=1;i<=n;i++) printf("%d ",p[i].d); puts("");
	for(int i=1;i<=n;i++) printf("%d ",q[i].d); puts("");
	return 0;
}
posted @ 2022-04-16 17:07  sz[sz]  阅读(45)  评论(0)    收藏  举报