题意

给定两个数组A[]B[]
要求构造一棵树满足
其拓扑序为A[]且DFS序为B[]
输出连边情况

分析

首先我们有一个很自然的思路
先将这棵树构造成一条满足B[]DFS序的链
进而,我们处理A[]数组
若当前的出现在之后
那么我们其实可以把以及其子树
链接到的右子树上
按顺序进行之后,得到的树便是研严格满足A[]拓扑序的树了

代码

//Nowcoder 7501 G
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

#define LL long long
#define Cl(X,Y) memset((X),(Y),sizeof(X))
#define FOR(i,A,B) for(int i=A;i<=B;i++)
#define BOR(i,A,B) for(int i=A;i>=B;i--)
#define De(X) cerr<<#X<<" = "<<X<<" "
#define Lowbit(X) (X & (-X))
#define Skip cout<<endl;
#define INF 0x3f3f3f3f
#define Mod 998244353
#define Rson (X<<1|1)
#define Lson (X<<1)
using namespace std;
const int MaxN=2e5+10;

int A[MaxN],B[MaxN],Total,Loc[MaxN],Side;
bool Jud[MaxN];

int main() {
    // File();
    // ios::sync_with_stdio(false);
    scanf("%d",&Total);
    FOR(i,1,Total) { scanf("%d",&A[i]); }
    FOR(i,1,Total) { scanf("%d",&B[i]); Loc[B[i]]=i; }
    printf("YES\n");
    FOR(i,1,Total) {
        FOR(j,Loc[A[i]]+1,Total) {
            if(Jud[B[j]]) break;
            ++Side;
            Jud[B[j]]=true;
            printf("%d %d\n",B[j],A[i]);
            if(Side==Total-1) break;
        }
        if(Side==Total-1) break;
    }
    // fclose(stdin);
    // fclose(stdout);
    // system("pause");
    return 0;
}