本文借鑑博文:
http://blog.csdn.net/panyanyany/article/details/6776300
最基本的線段樹操作(構造,插入更新,查找)
剛開始學線段樹,套一些網上的簡單題模板
題目:
代碼:
數組實現建樹
//#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "cstdio"
#include "sstream"
#include "queue"
#include "vector"
#include "string"
#include "stack"
#include "cstdlib"
#include "deque"
#include "fstream"
#include "map"
using namespace std;
typedef long long LL;
const int INF = 522133279;
const int MAXN = 1000000+100;
#define eps 1e-14
const int mod = 95041567;
int n,m;
int num[200000+100]; //各學生成績
struct t
{
int l,r;
int maxc;
}tree[2000000+100]; //數組法構造二叉數,基本邏輯是:根節點的位置爲i,那麼其兩個子節點的的位置爲2*i,2*i+1
int build(int root , int l , int r) //構造子線段
{
int mid;
tree[root].l=l;
tree[root].r=r;
if(l == r) //區間變成點,則區間對應的特性值確定
return tree[root].maxc = num[l];
mid = (l+r)/2; //否則繼續構造子線段
return tree[root].maxc = max(build(2*root,l,mid) , build(2*root+1,mid+1,r));
}
int find_max(int root , int l , int r)
{
if(tree[root].l >r || tree[root].r < l) //如果目的區間不在當前覆蓋區間,則返回一個不可達最小值
return 0;
if(tree[root].r <= r &&tree[root].l >= l) //如果目的區間包含當前覆蓋區間,則返回當前覆蓋區間的最大值
return tree[root].maxc;
return max(find_max(root*2,l,r),find_max(root*2+1,l,r)); //若區間相交,繼續尋找
}
int up(int root , int pos , int v)
{
if(pos < tree[root].l || pos > tree[root].r)
return tree[root].maxc;
if(pos == tree[root].l && pos == tree[root].r) //找到位置就更新
return tree[root].maxc = v;
return tree[root].maxc = max(up(root*2,pos,v),up(root*2+1,pos,v));
}
int main()
{
//freopen("in","r",stdin);
//freopen("out","w",stdout);
while(cin >> n >> m)
{
memset(tree,0,sizeof(tree));
for(int i = 1 ; i <= n ; i++)
cin >> num[i];
build(1,1,n);
for(int i= 0 ; i < m ; i++)
{
char c;
int a,b;
cin >> c >>a>> b;
if(c == 'Q')
cout << find_max(1,a,b) << endl;
else
{
num[a]=b;
up(1,a,b);
}
}
}
return 0;
}
指針實現建樹
//#pragma comment(linker, "/STACK:102400000,102400000")
#include "iostream"
#include "cstring"
#include "algorithm"
#include "cmath"
#include "cstdio"
#include "sstream"
#include "queue"
#include "vector"
#include "string"
#include "stack"
#include "cstdlib"
#include "deque"
#include "fstream"
#include "map"
using namespace std;
typedef long long LL;
const int INF = 522133279;
const int MAXN = 1000000+100;
#define eps 1e-14
const int mod = 95041567;
struct node
{
int l,r;
node *lc,*rc;
int maxc;
node(int _l , int _r):l(_l) , r(_r) , lc(NULL) , rc(NULL)
{}
}*root;
int num[200000+100];
int n,m;
int build(node **seg , int l , int r)
{
*seg = new node(l,r);
if(l == r)
return (*seg)->maxc = num[l];
int mid = (l+r)/2;
return (*seg)->maxc = max(build(&((*seg)->lc) , l , mid) , build(&((*seg)->rc) , mid+1,r));
}
int up(node **seg , int pos , int v)
{
if((*seg)->l > pos || (*seg)->r < pos)
return (*seg)->maxc;
if((*seg)->l == pos && (*seg)->r == pos)
return (*seg)->maxc = v;
return (*seg)->maxc = max(up(&((*seg)->lc) , pos , v) , up(&((*seg)->rc) , pos , v));
}
int find_max(node **seg , int l , int r)
{
if((*seg)->l > r || (*seg)->r < l)
return 0;
if((*seg)->r <= r && (*seg)->l >= l)
return (*seg)->maxc;
return max(find_max(&((*seg)->lc) , l , r) , find_max(&((*seg)->rc) , l , r));
}
void del(node **seg)
{
if((*seg) == NULL)
return;
del(&((*seg)->lc));
del(&((*seg)->rc));
delete *seg;
}
int main()
{
//freopen("in","r",stdin);
//freopen("out","w",stdout);
while(~scanf("%d%d",&n,&m))
{
getchar();
root = NULL;
for(int i = 1 ; i <= n ; i++)
scanf("%d",num+i);
getchar();
build(&root , 1,n);
for(int i = 0 ; i < m; i++)
{
char c;
int a,b;
scanf("%c%d%d",&c,&a,&b);
getchar();
if(c == 'Q')
printf("%d\n",find_max(&root , a , b));
else
{
num[a]=b;
up(&root,a,b);
}
}
del(&root);
}
return 0;
}