線段樹初探

2021-07-29 18:16:51 字數 3436 閱讀 6743

hdoj 1166 單點修改區間查詢維護區間和

題目傳送門:

模版題,樹狀陣列亦可a

#include 

#include

#include

using

namespace

std;

const

int max = 50005;

struct tree ;

tree tree[max * 4];

void update(int parent)

void createtree(int parent, int begin, int end)

int mid = (begin + end) / 2;

createtree(2 * parent, begin, mid);

createtree(2 * parent + 1, mid + 1, end);

update(parent);

return ;

}void modify(int x, int pos, int v)

int mid = (tree[x].begin + tree[x].end) / 2;

if (pos > mid) else

update(x);

return ;

}int query(int x, int begin, int end)

int mid = (tree[x].begin + tree[x].end) / 2;

int ret = 0;

if (begin <= mid) ret += query(x * 2, begin, end);

if (end > mid) ret += query(x * 2 + 1, begin, end);

return ret;

}int main(int argc, char

const *argv)

if (s[0] == 'a')

if (s[0] == 's') }}

return

0;}

hdoj 1754 單點修改區間查詢維護最大值

題目傳送門:

#include 

#include

#include

using

namespace

std;

const

int max = 200010;

struct t;

t t[max * 4];

inline max(int a, int b)

inline

void update(int x)

void create(int x, int begin, int end)

int mid = (begin + end) / 2;

create(x * 2, begin, mid);

create(x * 2 + 1, mid + 1, end);

update(x);

}void modify(int x, int pos, int v)

int mid = (t[x].begin + t[x].end) / 2;

if (pos > mid) else

update(x);

}int query(int x, int begin, int end)

int ret = 0;

int mid = (t[x].begin + t[x].end) / 2;

if (mid < end) ret = query(x * 2 + 1, begin, end);

if (mid >= begin) ret =max(ret,query(x * 2, begin, end));

return ret;

}int main(int argc, char

const *argv)

if (c == 'u') }}

return

0;}

hdoj 1540 區間修改單點查詢

題目傳送門:

線段樹的區間修改需要打tag標記,在下次modify或是query時pushdown tag標記,以提高時間效率。

這道題除了用到tag標記之外,還需要將樹對映到乙個線性結構上,為了實現區間修改的目的,使用dfs序。這樣樹上任意的一棵樹,在dfs序上這棵樹的根一定先於它的子節點先出現,且這棵樹在dfs序上是連續的。

#include 

#include

using

namespace

std;

const

int max = 50005;

int cnt, head[max];

int vis[max],left[max],right[max],now;

struct tree t[max * 4];

struct node edge[max];

void init(void)

void add(int u, int v)

void pushdown(int x)

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

int mid = (l+r) >> 1;

build(2*x, l, mid);

build(2*x+1,mid+1,r);

return ;

}void modify(int x,int l, int r, int v)

pushdown(x);

int mid = (t[x].l + t[x].r) >> 1;

if (l <= mid) modify(x*2,l,r,v);

if (r > mid) modify(x*2+1,l,r,v);

}int query(int x, int loc)

int mid = (t[x].l + t[x].r ) >> 1;

pushdown(x);

if (loc <= mid) return query(x*2,loc);

else

return query(x*2+1,loc);

}void dfs(int x)

right[x] = now;

return ;

}int main()

int root;

for (int i = 1; i <= n; i ++)

}dfs(root);

scanf("%d",&m);

printf("case #%d:\n",++ tc);

char c;int x,y;

for (int i = 1; i <= m; i ++) else

if (c == 't') }}

return

0;}

線段樹 02 構建線段樹

public inte ce merger 不能再縮小的基本問題是 對treeindex指向的節點的情況進行討論 public class segmenttree 在treeindex的位置建立表示區間 l.r 的線段樹 private void buildsegmenttree int treei...

線段樹 01 線段樹基礎

物理上 public class segmenttree public int getsize public e get int index 返回完全二叉樹的陣列表示中,乙個索引所表示的元素的左孩子節點的索引 private int leftchild int index 返回完全二叉樹的陣列表示中...

線段樹和zkw線段樹

好啦,我們就開始說說線段樹吧 線段樹是個支援區間操作和查詢的東東,平時的話還是蠻實用的 下面以最基本的區間加以及查詢區間和為例 線段樹顧名思義就是棵樹嘛,葉子節點是每個基本點,它們所對應的父親就是它們的和,具體如下圖 但是對於這樣的線段樹來說,操作所需的時間是遠達不到我們的要求的 會被t 因為我們會...