#include<iostream>
#include<stdio.h>
using namespace std;
#include<algorithm>
//这个事最大值
const int N=16;//16对应我话的图,所以保存
const int INF=100000;
struct Node
{
int min;//这个地方的最小值(如果这个点没有任何的值,那么为初始值,如果说有值,那么最大值和最小值相同)
int max;//这个地方的最大值
int min_diff;//?????????????????
}node[N*2];
//初始化
void init()
{
for(int i=1;i<(N*2);i++)
{
node[i].min=INF;//最小值给最大
node[i].max=-INF;//最大值给最小
node[i].min_diff=INF;//最小差异(因为最初这个题是来自中山大学的校赛)(就是求最小的差值)
}
}
//获取最小值
inline int min(int a,int b)
{
if(a>b) return b;
else return a;
}
//获取最大值
inline int max(int a,int b)
{
if(a>b) return a;
else return b;
}
//查询
inline int query()
{
return node[1].min_diff<N?node[1].min_diff:-1;//没有点,或者只有一个点。返回-1;
}
//注意,这个<n很重要,因为在过程中mid_diff会变小,变成9999,哈哈。注意啊。
//获取左孩子的节点
inline int get_left_child(int p)
{
return p*2;
}
//获取右孩子的节点
inline int get_right_child(int p)
{
return p*2+1;
}
//获取父亲的节点
inline int get_parent(int p)
{
return p/2;
}
//m是值为m的值,这个函数是用来获取数组的索引
//例如数字5,表示的元素在最后一行,也就是a[20]
inline int get_node(int m)
{
return m+N-1;
}
//更新p这个节点,主要是放到下面的两个函数中使用。
void update(int p)
{
//获取左孩子节点和有孩子节点
int left_child =get_left_child(p);
int right_child=get_right_child(p);
//把左右孩子的最小值给p.min 把左右孩子的最大值给p.max
node[p].min=min(node[left_child].min,node[right_child].min);
node[p].max=max(node[left_child].max,node[right_child].max);
//这里可以不管
node[p].min_diff=min(node[left_child].min_diff,node[right_child].min_diff);//最近点对可能出现在左或者右儿子节点
node[p].min_diff=min(node[p].min_diff,node[right_child].min-node[left_child].max);
}
//增加节点m
void add(int m)
{
//获取游标
int cur=get_node(m);
if(node[cur].min==INF)//点m不在树中
{
//赋初值
node[cur].min=m;
node[cur].max=m;
//向上更新
do
{
cur=get_parent(cur);
update(cur);
}while(cur>1);
}
}
//删除m这个点
void remove(int m)
{
int cur=get_node(m);
if(node[cur].min<INF)
{
//把值变成原来的值
node[cur].min=INF;
node[cur].max=-INF;
//向上更新
do
{
cur=get_parent(cur);
update(cur);
}while(cur>1);
}
}
int n,m;
int main()
{
freopen("input.txt","r",stdin);
int i,j;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(i=0;i<n;i++)
{
}
}
/*
int casen;
scanf("%d",&casen);
while(casen--)
{
init();//初始化
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
char cmd[10];
scanf("%s",cmd);
if(cmd[0]=='q')//查询
{
printf("%d\n",query());
}
else
{
int m;
scanf("%d",&m);
if(cmd[0]=='g')//产生
{
add(m);
}
else//移除
{
remove(m);
}
}
}
if(casen>0)
{
puts(" ");
}
}
*/
return 0;
}
/*
1 利用内连函数
2 问题一:min和max用来做什么?
答:这个是一个很重要的东西,是基本的东西,类似于路标。
3 这一句不理解node[p].min_diff=min(node[p].min_diff,node[right_child].min-node[left_child].max);
答:什么也不说,看图。
*/