árbol segmento dinámico receta

Requisito previo abierta punto dinámico es Presidente del árbol, se considera que es un árbol Presidente Keqianyuxi aprenderlo.

comprensión personal de la dinámica de un árbol binario similar a la lista prescrita para lograr, hay dos punteros al hijo a la izquierda y la derecha. Dinámica abierta punto más o menos de la misma manera. Con el fin de la gama máxima como un ejemplo, el árbol segmento mantiene tres información:

  1. hijo actual número de nodo izquierdo del nodo
  2. Son secundario en el nodo actual número de nodo
  3. valor máximo del intervalo

 La primera contribución, la contribución en función de

int build(){
	++cnt;
	c[cnt].l = 0;
	c[cnt].r = 0;
	c[cnt].max = -inf;
	return cnt;
}

Representar la adición de un nuevo nodo, sobre el hijo de los nodos recién añadidos son 0 (vacío), la corriente vuelve número de nodo a cabo. Si el nuevo nodo aumenta, debe ser desde el momento de la visita se encontró ningún padre nodo hacia abajo, esto es la necesidad de crear un nuevo nodo hijo, entonces el número de nodo principal hacia la izquierda o nodo hijo derecho es el número actual del nuevo nodo.

El tiempo inicial, la necesidad de una raíz, root = build ()crear un nuevo punto, este punto como la raíz de la misma.

Cuando se realiza la actualización de un solo punto, por ejemplo, a un índice índicedel cambio de posición, una función de actualización y el árbol segmento es similar a la siguiente

void insert(int l, int r, int k, int ind, int d){
	if (l == r){
		c[k].max += d;
		return;
	}
	int mid = (l + r) >> 1;
	if (ind <= mid){
		if (c[k].l == 0)c[k].l = build();
		insert(l, mid, c[k].l, ind, d);
	}
	else{
		if (c[k].r == 0)c[k].r = build();
		insert(mid + 1, r, c[k].r, ind, d);
	}
	c[k].max = max(c[c[k].l].max, c[c[k].r].max);
}

Si encuentra este punto para la actualización y el retorno, de lo contrario, seguir buscando para encontrar el tiempo o el intervalo en dos, mirada en este punto es qué sección, por sólo un paseo por el hijo del nodo actual, se toman el tiempo para juzgar , en el supuesto de que el hijo está tomando el nodo izquierdo, si el hijo izquierdo existir, continúan caminando, no existe, entonces usted necesita para crear un nodo hijo dejó continuar a pie. Y el resto es el mismo que el árbol segmento.

Consulta es similar, no los repita.

#include <bits/stdc++.h>
#define mem(a, b) memset(a, b, sizeof a)
using namespace std;
const int N = 310;
const int inf = 0x7fffffff;
struct p{
	int l, r, max;
};
p c[N * 4];
int root, cnt;
int build(){
	++cnt;
	c[cnt].l = 0;
	c[cnt].r = 0;
	c[cnt].max = -inf;
	return cnt;
}
void insert(int l, int r, int k, int ind, int d){
	if (l == r){
		c[k].max = d;
		return;
	}
	int mid = (l + r) >> 1;
	if (ind <= mid){
		if (c[k].l == 0)c[k].l = build();
		insert(l, mid, c[k].l, ind, d);
	}
	else{
		if (c[k].r == 0)c[k].r = build();
		insert(mid + 1, r, c[k].r, ind, d);
	}
	c[k].max = max(c[c[k].l].max, c[c[k].r].max);
}
int query(int ind, int k, int l, int r){
	if (l == r){
		return c[k].max;
	}
	int mid = (l + r) >> 1;
	if (ind <= mid)return query(ind, c[k].l, l, mid);
	else return query(ind, c[k].r, mid + 1, r);
}
int main()
{
	root = build();
	insert(1, 5, root, 2, 1);
	insert(1, 5, root, 1, 2);
	insert(1, 5, root, 3, 4);
	insert(1, 5, root, 4, 3);
	insert(1, 5, root, 5, 5);
	for (int i = 1; i <= 5; i++){
		printf("%d : %d\n",i, query(i, root, 1, 5));
	}
	return 0;
}

 

Publicados 204 artículos originales · elogios ganado 13 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/weixin_43701790/article/details/104427667
Recomendado
Clasificación