题意:
有一个原始序列
a
a
a,现在构造一些序列:
- 构造长度为 n − 1 n-1 n−1的 b b b序列,满足 b [ i ] = min ( a [ i ] , a [ i + 1 ] ) b[i]=\min(a[i],a[i+1]) b[i]=min(a[i],a[i+1])
- 构造长度为 n − 1 n-1 n−1的 c c c序列,满足 c [ i ] = max ( a [ i ] , a [ i + 1 ] ) c[i]=\max(a[i],a[i+1]) c[i]=max(a[i],a[i+1])
- 构造长度为 n − 1 n-1 n−1的排列 p p p。
- 构造长度为 n − 1 n-1 n−1的 b ′ b' b′序列,满足 b ′ [ i ] = b [ p [ i ] ] b'[i]=b[p[i]] b′[i]=b[p[i]]
- 构造长度为 n − 1 n-1 n−1的 c ′ c' c′序列,满足 c ′ [ i ] = c [ p [ i ] ] c'[i]=c[p[i]] c′[i]=c[p[i]]
给出
b
′
b'
b′序列和
c
′
c'
c′序列,求出任意一个满足条件的
a
a
a序列。如果没有满足的
a
a
a序列,输出
−
1
-1
−1。
显而易见只要有一个
i
i
i满足
b
′
[
i
]
>
c
′
[
i
]
b'[i]>c'[i]
b′[i]>c′[i],那么就是无解的。
考虑到只有这两种情况:
- a [ i ] = b [ i ] , a [ i + 1 ] = c [ i ] a[i]=b[i],a[i+1]=c[i] a[i]=b[i],a[i+1]=c[i]
- a [ i ] = c [ i ] , a [ i + 1 ] = b [ i ] a[i]=c[i],a[i+1]=b[i] a[i]=c[i],a[i+1]=b[i]
所以就可以将每对
b
′
[
i
]
b'[i]
b′[i]和
c
′
[
i
]
c'[i]
c′[i]连上边。
然后对于建出来的一张图检测它是否存在欧拉路就可以了。
c
o
d
e
:
code:
code:
#include <bits/stdc++.h>
using std::cin;
using std::cout;
#define regi register int
int n;
int a[1000001];
int b[1000001];
int in[1000001];
int Dis[1000001],Dn;
int head[2000001],tot=1;
int vis[2000001];
int ans[10000001],Tot;
struct edge{
int to;
int nxt;
}e[5000001];
inline void add(int x,int y){
e[++tot]={y,head[x]};
head[x]=tot;
}
void dfs(int x){
for(regi &i=head[x];i;i=e[i].nxt){
if(vis[i])
continue;
regi y=e[i].to;
vis[i]=vis[i^1]=1;
dfs(y);
}
ans[++Tot]=x;
}
main(){
std::ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(regi i=1;i<=n-1;++i){
cin>>a[i];
Dis[i]=a[i];
}
for(regi i=1;i<=n-1;++i){
cin>>b[i];
Dis[n+i-1]=b[i];
}
for(regi i=1;i<=n;++i){
if(a[i]>b[i])
return std::cout<<-1,0;
}
std::sort(Dis+1,Dis+2*n-1);
Dn=std::unique(Dis+1,Dis+2*n-1)-Dis-1;
for(regi i=1,l,mid,r;i<n;++i){
l=1,r=Dn;
while(l<r){
mid=l+r+1>>1;
if(Dis[mid]<=a[i])
l=mid;
else
r=mid-1;
}
a[i]=l;
l=1,r=Dn;
while(l<r){
mid=l+r+1>>1;
if(Dis[mid]<=b[i])
l=mid;
else
r=mid-1;
}
b[i]=l;
}
for(regi i=1;i<n;++i){
add(a[i],b[i]);
add(b[i],a[i]);
in[a[i]]++;
in[b[i]]++;
}
int flag=0;
for(regi i=1;i<=Dn;++i)
flag+=(in[i]&1);
if(flag!=0&&flag!=2)
return std::cout<<-1,0;
flag=0;
for(regi i=1;i<=Dn;++i)
if(in[i]&1){
dfs(i);
flag=1;
break;
}
if(!flag)
dfs(1);
if(Tot!=n)
return std::cout<<-1,0;
for(regi i=1;i<=n;++i)
cout<<Dis[ans[i]]<<" ";
return 0;
}