树(不知道叫什么名字,以前也很有用)(增加注释)

本文探讨了C++模板元编程技术在数据结构优化中的应用,通过实例展示了如何利用元编程实现高效的数据结构操作,提高了程序的运行效率。
#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);
答:什么也不说,看图。

                      
                     
*/

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值