日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

线段树简介

發布時間:2023/11/27 生活经验 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 线段树简介 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.構造 void build(int node, int begin, int end);

主要思想是遞歸構造,如果當前節點記錄的區間只有一個值,則直接賦值,否則遞歸構造左右子樹,最后回溯的時候給當前節點賦值

#include <iostream>  
using namespace std;  const int maxind = 256;  
int segTree[maxind * 4 + 10];  
int array[maxind];   
/* 構造函數,得到線段樹 */  
void build(int node, int begin, int end)    
{    if (begin == end)    segTree[node] = array[begin]; /* 只有一個元素,節點記錄該單元素 */  else    {     /* 遞歸構造左右子樹 */   build(2*node, begin, (begin+end)/2);    build(2*node+1, (begin+end)/2+1, end);   /* 回溯時得到當前node節點的線段信息 */    if (segTree[2 * node] <= segTree[2 * node + 1])    segTree[node] = segTree[2 * node];    else    segTree[node] = segTree[2 * node + 1];    }    
}  int main()  
{  array[0] = 1, array[1] = 2,array[2] = 2, array[3] = 4, array[4] = 1, array[5] = 3;  build(1, 0, 5);  for(int i = 1; i<=20; ++i)  cout<< "seg"<< i << "=" <<segTree[i] <<endl;  return 0;  
}   

2.區間查詢int query(int node, int begin, int end, int left, int right);

(其中node為當前查詢節點,begin,end為當前節點存儲的區間,left,right為此次query所要查詢的區間)

主要思想是把所要查詢的區間[a,b]劃分為線段樹上的節點,然后將這些節點代表的區間合并起來得到所需信息

int query(int node, int begin, int end, int left, int right)    
{   int p1, p2;    /*  查詢區間和要求的區間沒有交集  */  if (left > end || right < begin)    return -1;    /*  if the current interval is included in  */    /*  the query interval return segTree[node]  */  if (begin >= left && end <= right)    return segTree[node];    /*  compute the minimum position in the  */  /*  left and right part of the interval  */   p1 = query(2 * node, begin, (begin + end) / 2, left, right);   p2 = query(2 * node + 1, (begin + end) / 2 + 1, end, left, right);    /*  return the expect value  */   if (p1 == -1)    return p2;    if (p2 == -1)    return p1;    if (p1 <= p2)    return  p1;    return  p2;      
}   

3.區間或節點的更新 及 線段樹的動態維護update

單節點更新

void Updata(int node, int begin, int end, int ind, int add)/*單節點更新*/    
{    if( begin == end )    {    segTree[node] += add;    return ;    }    int m = ( left + right ) >> 1;    if(ind <= m)    Updata(node * 2,left, m, ind, add);    else    Updata(node * 2 + 1, m + 1, right, ind, add);    /*回溯更新父節點*/    segTree[node] = min(segTree[node * 2], segTree[node * 2 + 1]);     }   

區間更新(線段樹中最有用的)

void Change(node *p, int a, int b) /* 當前考察結點為p,修改區間為(a,b]*/  {  if (a <= p->Left && p->Right <= b)  /* 如果當前結點的區間包含在修改區間內*/  {  ...... /* 修改當前結點的信息,并標上標記*/  return;  }  Push_Down(p); /* 把當前結點的標記向下傳遞*/  int mid = (p->Left + p->Right) / 2; /* 計算左右子結點的分隔點 if (a < mid) Change(p->Lch, a, b); /* 和左孩子有交集,考察左子結點*/  if (b > mid) Change(p->Rch, a, b); /* 和右孩子有交集,考察右子結點*/  Update(p); /* 維護當前結點的信息(因為其子結點的信息可能有更改)*/  }  

?

?摘自:http://blog.csdn.net/metalseed/article/details/8039326

轉載于:https://www.cnblogs.com/gaoss/p/4963294.html

總結

以上是生活随笔為你收集整理的线段树简介的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。