線段樹(區間樹)的廣泛應用

2021-10-03 05:51:59 字數 3202 閱讀 4563

線段樹一般是解決能夠區間話的問題,對給定的結點進行統一操作,時間複雜度為o(nlogn)

一般結點可寫成如下**:

struct node

int getlength()

}tree[maxn<<2];//開四倍空間,畫個二叉樹就知道了

對葉子結點向上更新:

void pushup(int rt)//向上更新

對葉子結點向下更新:

void pushdown(int rt)//向下更新

建立區間樹:

//建立區間樹

void bulidtree(int rt,int l,int r)//建樹

int mid=tree[rt].getmid();

bulidtree(rt<<1,l,mid); //建立左子樹

bulidtree(rt<<1|1,mid+1,r);//建立右子樹

pushup(rt);//向上更新

}

單點查詢:

void querypoint(int rt,int id,int &x)

int mid=tree[rt].getmid();

if(id<=mid) querypoint(rt<<1,id,x);//查詢左子樹

else querypoint(rt<<1|1,id,x);//查詢右子樹

}

單點更新:

void updatapoint(int rt,int id,int x)

if(tree[rt].lay)//如果該節點被標記,則向下更新

pushdown(rt);

int mid=tree[rt].getmid();

if(id<=mid) updatapoint(rt<<1,id,x);//更新左子樹

else updatapoint(rt<<1|1,id,x);//更新右子樹

pushup(rt);//向上更新

}

區間查詢:

int querypart(int rt,int l,int r)

int ans=0;//每乙個結點的和

int mid=tree[rt].getmid();

if(l<=mid) ans+=querypart(rt<<1,l,r);//查詢左子樹

if(r>=mid+1) ans+=querypart(rt<<1|1,l,r);//查詢右子樹

return ans;//返回給父節點

}

區間更新:

void updatapart(int rt,int l,int r,int x)

if(tree[rt].lay)//如果該節點被標記,則向下更新

pushdown(rt);

int mid=tree[rt].getmid();

if(l<=mid) updatapart(rt<<1,l,r,x);//更新左子樹

if(r>=mid+1) updatapart(rt<<1|1,l,r,x);//更新右子樹

pushup(rt);//向上更新

}

例項poj3264:

描述:對於每天的**,農夫john的n頭奶牛(1≤n≤50,000)總是按照相同的順序排列。一天,農夫約翰決定和幾頭牛組織一場極限飛盤遊戲。為了簡單起見,他將從**佇列中選取一系列連續的奶牛來玩這個遊戲。然而,對於所有的牛來說,它們的身高不應該相差太多。

農民約翰列出了q(1≤q≤20萬)個可能的奶牛群和它們的高度(1≤高度≤1,000,000)。對於每一組,他想讓你幫助確定小組中最矮和最高的牛之間的身高差異。

輸入

第1行:兩個以空格分隔的整數,n和q。

行2 . .n+1:第i+1行包含乙個整數,它是cow i的高度

行n + 2 . .n+q+1:兩個整數a和b(1≤a≤b≤n),表示奶牛從a到b的範圍。

輸出

行1 . .問:每行包含乙個整數,該整數是對應答的響應,並指示範圍內最高和最低奶牛之間的身高差異。

樣例輸入

6 317

3425

1 54 6

2 2

輸出:

6

30

ac**: 

#include #include #include #include #include using namespace std;

const int maxn=1e5+5;

const int inf=0x3f3f3f3f;

struct node

}cow[maxn<<2];

int arr[maxn];

int n,m;

int k=0;

int maxe,mine;

void build(int rt,int l,int r)

int mid=cow[rt].getmid();

build(rt<<1,l,mid);

build(rt<<1|1,mid+1,r);

cow[rt].weight=cow[rt<<1].weight+cow[rt<<1|1].weight;

cow[rt].maxw=max( cow[rt<<1].maxw,cow[rt<<1|1].maxw );

cow[rt].minw=min( cow[rt<<1].minw,cow[rt<<1|1].minw );

}void query(int rt,int l,int r,int &maxe,int &mine)

int mid=cow[rt].getmid();

if(l<=mid) query(rt<<1,l,r,maxe,mine);

if(r>=mid+1) query(rt<<1|1,l,r,maxe,mine);

}int main()

build(1,1,n);

while(m--)

return 0;

}

線段樹(區間樹)

目錄 為什麼要使用線段樹 什麼是線段樹 線段樹融合介面 線段樹實現 線段樹例題 融合介面 author administrator param public inte ce merger package com.suanfa.segmenttree 線段樹 區間樹 author administra...

線段樹 區間樹

每乙個節點儲存的是乙個區間中相應統計值 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treeindex,int l,int r int lefttreeindex leftchild treeindex int rig...

區間樹和線段樹

注意 區間樹和線段樹不一樣哦,線段樹是一種特殊的區間樹。區間樹 區間樹是在紅黑樹基礎上 進行擴充套件得到的支援以區間為元素的動態集合的操作,其中每個節點的關鍵值是區間的左端點。通過建立這種特定的結構,可是使區間的元素的查詢和插入都可以在o lgn 的時間內完成。相比於基礎的紅黑樹資料結構,增加了乙個...