本文借鉴博文:
http://blog.youkuaiyun.com/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;
}