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;
}
浙公网安备 33010602011771号