arbre segment de prescription dynamique

Condition préalable point ouvert est dynamique président de l'arbre, est considéré comme un arbre d'apprentissage Président Keqianyuxi il.

compréhension personnelle de la dynamique d'un arbre binaire semblable à la liste de prescription pour obtenir, il y a deux pointeurs vers le fils gauche et à droite. point ouvert dynamique à peu près de la même façon. Afin de portée maximale, par exemple, l'arbre de segment maintient trois informations:

  1. fils actuel numéro de noeud gauche du noeud
  2. Son droit nœud actuel numéro de noeud
  3. valeur maximale intervalle

 Première contribution, la contribution en fonction de

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

Représenter l'ajout d'un nouveau nœud, sur le fils des nœuds nouvellement ajoutés sont 0 (vide), le numéro de noeud courant sur le rendement. Si les nouvelles augmentations de nœud, il doit être à partir du moment de la visite n'a trouvé aucun noeud parent vers le bas, c'est la nécessité de créer un nouveau nœud de fils, puis le numéro de nœud parent gauche ou nœud fils droit est le nombre actuel du nouveau nœud.

Le temps initial, la nécessité d'une racine, root = build ()créer un nouveau point, ce point comme la racine de celui - ci.

Lors de la mise à jour en un seul point, par exemple, à un indice indicedu changement de position, une fonction de mise à jour et l'arbre de segment est similaire à celui - ci

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 vous trouvez ce point mettre à jour et retour, sinon, continuez à chercher à trouver le temps ou l'intervalle en deux, regardez ce point est que la section, pour seulement une promenade autour du fils du noeud courant, prenez le temps de juger , en supposant que le fils prend le nœud gauche, si exist fils gauche, continuer à marcher, ne pas exister, vous devez créer un fils de nœud à gauche pour continuer la marche. Et le reste est le même que l'arbre du segment.

Requête est similaire, ne pas les répéter.

#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;
}

 

Publié 204 articles originaux · éloge de won 13 · vues 10000 +

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43701790/article/details/104427667
conseillé
Classement