Arbre de segment détaillée

vue d'ensemble

  arbre segment est un arbre de recherche binaire, chaque nœud de l'arbre sont les informations d'intervalle de maintenance, noeud racine du segment de l'information sectorielle peut être calculée par des informations sous-arbre gauche et sous-arbre droite de la plage, nous parlons de satisfaire plus (c.-à- ).

Plusieurs intervalle d'addition commun: nombre total de somme numérique + = gauche et une section droite et une section numérique

          Le GCD total = PGCD (gauche, droite)

          gamme de produits Nombre total de multiplication * = gamme de produits gauche et à droite

          Total maximum = max (intervalle maximum gauche et la valeur maximale intervalle à droite) // De même minimum

  Il est quoi est-il? Il peut résoudre la gamme de problèmes, la requête peut être un seul point dans le journal de temps (n), la requête d'intervalle, modifier, etc. un seul point, par exemple, le titre vous donne une séquence de longueur n, k opérations requises, chaque opération peut changer la valeur d'un point, vous pouvez également vérifier l'intervalle l à R, et, s'il y a une seule requête et vous pouvez utiliser le préfixe, plus le préfixe et modifier mourir, si la violence le font dans la complexité de la requête est O (nk), mais Si un arbre de segment peut être optimisé pour O (klogn).

Il ressemble? Comment faire?

  Pour la durée d'un entretien des arbres du segment 8, il est l'idée de forme longue comme ceci:

             

  La gamme totale est naturellement 1-8, pour laquelle la section de gauche est un 4/1 de la section droite est de 5 à 8, parce que l'arbre de segments de noyau est la nature bipartite, l'intervalle [L, R] de l'intervalle gauche [L, m] de la section droite est [m + 1, R], m est égal à (L + R) / 2. M est à noter que le point final appartient à la partie gauche.

  Ensuite, si la valeur réelle qui lui est attribué, pour vous dire huit chiffres étaient 12.345.678, il est la situation réelle si longtemps:

              

  Si la référence à elle, chacune des couches de haut en bas, de gauche à droite pour les petits à un grand nombre, peut être vu, lorsque n numéro du nœud racine, le sous-arbre gauche n ° 2 * n, 2 est un sous-arbre droit * n + 1:

               

   Comment ça existe? Utilisez un tableau pour stocker, un [i] représente les informations d'étiquettes pour le noeud i, puis ouvrez le tableau soit? réseau spatial 1 est le nombre de noeuds, pour ce segment de ligne d'arbre de longueur n, le nombre de noeuds, il?

 

   Lorsque n est une puissance de 2, alors l'arbre de segment est un arbre binaire complet, qui est le nombre de couches de log 2 (n) + +1, alors le nombre de noeuds est de deux couches -1- à -dire 2n-1, où n est une puissance de 2 lorsque l'arbre du segment ne sera pas si beau, un tableau de noeuds de feuille d'espace ne sont pas nécessairement contiguës:

L'arbre de segment n = 10 par exemple:

  

   Vous pouvez voir ce n'est pas le nombre total de binaire, arbre binaire complet de n pour atteindre 16, si le nombre d'espace ouvert 2n-1 est également 19 selon la formule ci - dessus, mais l'indice maximum réel allé à 25, ne peut pas répondre, donc nous était ouvert plus, à la puissance n est pas 2, nous faisons une couche supplémentaire d'espace ouvert, c'est - à - dire n = 10 n = espace nous avons ouvert 16, n = 17 n = espace nous avons ouvert 32 , log 2 (n) + +1 n est le nombre de couches pour la puissance de 2, afin de faciliter pas si n est une puissance de 2, nous avons une multi-couche d'espace ouvert pour elle, de sorte que le nombre de couches log = 2 (n) + 1 + 1, le nombre total de noeuds à l'ouverture 2 log 2 (n) + 1 + 1 -1, à savoir 4n-1, 4 ligne de pliage de telle sorte que l'ouverture, complète la preuve!

ligne de code arbre ordinaire détaillé

  Pour ouvrir les variables: maxn est la portée maximale de n, A [maxn] La valeur de mémorisation de sujet n information, correspondant au noeud feuille de l'arbre de segment a [4 * maxn] est le segment de l'espace de l'arbre, le noeud de référence est i.

Pour plus d'informations de noeud d'entretien

  Notez ce que les informations sont stockées noeud, ce code est stocké et la gamme:

vide pushup ( int rt) { 
    a [rt] = a [rt << 1 ] + a rt [<< 1 | 1 ]; 
}

contribuer

  建树的过程就是一直递归到叶子节点,然后把当前编号的空间赋值为对应题目的信息,在递归结束的时候要维护区间信息

 1 void build(int l,int r,int rt){//对于 l 到 r 的一颗线段树建树 
 2     if(l==r){//代表已经递归到叶子节点 
 3         a[rt]=A[l];
 4         return ;
 5     }
 6     int m=l+r>>1;
 7     build(l,m,rt<<1);//建左子树 
 8     build(m+1,r,rt<<1|1);//建右子树 
 9     pushup(rt);//左右子树建好之后维护当前区间的信息 
10 }

 单点更新

  单点更新其实就是一个找叶子节点编号的二分过程,当你找到对应叶子节点的位置,你想干嘛干嘛,这里是对应位置加上val值:

 1 void update(int pos,int val,int l,int r,int rt){//在pos位置加上val
 2     if(l==r){//代表已经递归到叶子节点 
 3         a[rt]+=val;
 4         return;
 5     }
 6     int m=l+r>>1;
 7     if(pos<=m)//目标位置在左边 
 8         update(pos,val,l,m,rt<<1);
 9     else//在右边 
10         update(pos,val,m+1,r,rt<<1|1);
11     pushup(rt);//更新完维护信息 
12 }

单点查询

  单点查询其实和单点更新本质上相同,就是找到叶子节点,然后想干嘛干嘛

int search(int pos,int l,int r,int rt){
    if(l==r){
        return a[rt];
    }
    int m=l+r>>1;
    if(pos<=m)
        return search(pos,l,m,rt<<1);
    else
        return search(pos,m+1,r,rt<<1|1);
}

区间查询

  在区间查询中,有两个区间,一个是查询区间我们设为【L,R】,一个是递归区间设为【l,r】。假如我们要查询区间和,设为ans。

 1 int query(int L,int R,int l,int r,int rt){
 2     if(L<=l&&r<=R){
 3         return a[rt];//第一种情况,直接贡献 
 4     }
 5     int m=l+r>>1;
 6     int ans=0;
 7     if(L<=m)//递归区间的左边含有查询 
 8         ans+=query(L,R,l,m,rt<<1);
 9     if(R>m)
10         ans+=query(L,R,m+1,r,rt<<1|1);
11     return ans;//统计二三情况的贡献,返回最终值 
12 }

  分三种情况:

  一是递归区间属于查询区间,L<=l&&r<=R,就是说本节点所表示的信息你全部都要,那就贡献到ans里。

  二是递归区间的左边有查询区间,L<=m,但本节点信息你不是全部要,得递归深一点,直到满足情况一才贡献ans,遂令下一个递归区间为【l,m】。

  三是递归区间的右边有查询区间,R>m,但本节点信息你不是全部要,得递归深一点,直到满足情况一才贡献ans,遂令下一个递归区间为【R,m+1】。

             

  

 区间更新

  假如我们要将区间【L,R】中的每一个端点加上一个值val,如果区间更新用R-L+1个单点更新来做,那么复杂度要去到O(长度*logn),那么最坏长度为整个序列那么长,就是nlogn了。为了降低时间复杂度,我们引入懒标记这一概念。

  每一个节点都有一个懒标记值,懒标记——表示本节点的左右子树有区间更新需求但尚未更新。懒标记顾名思义就是太懒了,懒得递归下去,打个标记,之后如果要用到就顺便更新了。

  

  举个例子,对于n=10,各个端点值为1 2 3 4 5 6 7 8 9 10,

 

 

 

 

 

 

 

 

 

 

 

 

Je suppose que tu aimes

Origine www.cnblogs.com/qq2210446939/p/12215363.html
conseillé
Classement