#include<cstdio>
#include<string>
#include<iostream>
#include <algorithm>//含有fill()等
#include <cmath>
#include<queue>
#include<unordered_set>
#include<set>
#include<map>
#include<vector>
#include<unordered_map>
#include <cstdlib>//含有free,malloc等;含有NULL
using namespace std;
//A1141 :unordered_map
const int INF=1e9; //fill(map[0],map[0]+maxn*maxn,INF);
const int maxn=30;
//需要打印排名列表
struct node{
int val;
node *left,*right;
};
int getHeight(node* tree){
if(tree==NULL) return 0;
int l=getHeight(tree->left);
int r=getHeight(tree->right);
return max(l,r)+1;//返回左右子树中最高的高度+本身节点的高度
}
node* LL(node* tree){
//对节点进行右旋操作
node* temp=tree->left;
tree->left=temp->right;
//由于要将原先根变为当前根节点的右子树:所以原来左子树根节点的右子树
//要换到原先根节点的左子树上
temp->right=tree;
return temp;
}
node* RR(node* tree){
//对节点进行左旋 :和LL相反即可
node* temp=tree->right;//temp是新的树的根节点
tree->right=temp->left;
temp->left=tree;
return temp;
}
//注意可以复用!右旋和左旋的方法:看清楚调用的是哪个
node* RL(node* tree){
//对节点的右子树右旋,对节点左旋
tree->right=LL(tree->right);
return RR(tree);
}
node* LR(node* tree){
//先对节点的左子树进行左旋,再对节点进行右旋
tree->left=RR(tree->left);
return LL(tree);
}
node* insert(node* tree,int val){//注意参数传的是指针
if(tree==NULL){
tree=new node();
tree->val=val;
}else if(tree->val>val){
//左子树走
tree->left=insert(tree->left,val);//AVL树是BST
//计算该节点的平衡因子:判断是否需要旋转
//由于插入的是左子树:所以如果失衡只能是左边大于右边两个
int l=getHeight(tree->left),r=getHeight(tree->right);
if(l-r>=2){
//判断插入的是LR还是LL
if(val<tree->left->val){
//LL:tree整体做LL变换
tree=LL(tree);
}else{
//LR
tree=LR(tree);
}
}
}else{
//插入根节点的右子树
tree->right=insert(tree->right,val);
int l=getHeight(tree->left),r=getHeight(tree->right);
if(r-l>=2){
//判断是RR还是RL
if(val>tree->right->val)tree=RR(tree);
else tree=RL(tree);
}
}
return tree;//只是插入的操作
}
vector<int> path;
int isComplete=1,after=0;
//层次遍历并且判断是否是完全二叉树
void level(node* tree){
queue<node*>q;
q.push(tree);
while(!q.empty()){
node* now=q.front();
q.pop();
//在pop输出的时候:加入层次遍历(注意位置)
path.push_back(now->val);
if(now->left!=NULL){
if(after)isComplete=0;
q.push(now->left);
}else{
after=1;//说明缺孩子节点的节点存在
}
if(now->right!=NULL){
if(after)isComplete=0;
q.push(now->right);
}else{
after=1;
}
}
}
int main(){
int n,temp;
scanf("%d",&n);
node *tree =NULL;//根节点
for(int i=0;i<n;i++){
scanf("%d",&temp);
tree=insert(tree,temp);
}
level(tree);
for(int i=0;i<path.size();i++){
printf("%d",path[i]);
if(i!=path.size()-1){
printf(" ");
}else{
printf("\n");
}
}
printf("%s",isComplete?"YES":"NO");
return 0;
}