线段树建树的时间复杂度为O(nlogn) 查询、修改的复杂度为O(logn)
样例代码:
线段树1:区间最值,单点修改
1 #include <cstdio>
2 #include <algorithm>
3 #define MAXN 10000
4 using namespace std;
5 int ans[10000];
6 struct Node//线段树定义
7 {
8 int val;
9 Node *ls,*rs;
10 }pool[MAXN];
11
12 Node * newNode()//申领新节点
13 {
14 static int cnt = 0;
15 return &pool[cnt++];
16 }
17 int pushup(Node *ls , Node *rs)//更新节点
18 {
19 return max(ls->val,rs->val);
20 }
21 Node * build(int l , int r)//建树
22 {
23 Node *cur =newNode();
24 int mid;
25 if(l < r)
26 {
27 mid = (l+r)/2;
28 cur -> ls = build(l,mid);
29 cur -> rs = build(mid + 1,r);
30 }
31 else
32 {
33 cur -> val= ans[l];
34 cur -> ls = NULL;
35 cur -> rs = NULL;
36 return cur;
37 }
38 cur->val = pushup(cur->ls,cur->rs);
39 return cur;
40 }
41 int query(Node * cur ,int l , int r , int a, int b)//查询
42 {
43 int mid = (l+r)/2,res = 0;
44 if(a <= l && b >= r) return cur -> val;
45 else
46 {
47 if(a <= mid) res = max(res,query(cur->ls,l,mid,a,b));
48 if(b > mid) res = max(res,query(cur->ls,mid+1,r,a,b));
49 return res;
50 }
51 }
52 void modify(Node *cur,int l , int r, int p,int v)//单点修改
53 {
54 int mid = (l+r)/2;
55 if(l == r)cur -> val = v;
56 else
57 {
58 if(p <= mid) modify(cur->ls,l,mid,p,v);
59 else modify(cur->rs,mid+1,r,p,v);
60 cur->val = pushup(cur->ls,cur->rs);
61 }
62 return;
63 }
64 int main()
65 {
66 int n,m;
67 int i,k,l,r;
68 Node *head;
69 scanf("%d%d",&n,&m);
70 for(i = 1 ; i <= n ; i++)
71 {
72 scanf("%d",&ans[i]);
73 }
74 head = build(1,n);
75 for(i = 1 ; i <= m ; i++)
76 {
77 scanf("%d%d%d",&k,&l,&r);
78 if(k == 1)
79 {
80 modify(head,1,n,l,r);
81 }
82 else
83 {
84 printf("%d\n",query(head,1,n,l,r));
85 }
86 }
87 return 0;
88 }
线段树2:区间求和,单点修改:
#include <cstdio>
#include <algorithm>
#define MAXN 2000100
using namespace std;
int ans[MAXN];
struct Node
{
Node *ls,*rs;
long long int sum;
}pool[MAXN];
Node* newNode()
{
static int cnt = 0;
return &pool[cnt++];
}
void pushup(Node* cur)
{
cur->sum = cur->ls->sum + cur->rs->sum;
return;
}
Node* build(int l , int r)
{
Node* cur = newNode();
if(l < r)
{
int mid = (l+r)/2;
cur->ls = build(l,mid);
cur->rs = build(mid+1,r);
pushup(cur);
}
else
{
cur->ls = NULL;
cur->rs = NULL;
cur->sum = ans[l];
}
return cur;
}
long long int query(Node* cur , int l, int r , int a, int b)
{
long long int res = 0;
int mid = (l+r)/2;
if(a <= l && b >= r) return cur->sum;
else
{
if(a <= mid) res +=query(cur->ls,l,mid,a,b);
if(b > mid) res += query(cur->rs,mid+1,r,a,b);
}
return res;
}
void mqery(Node* cur,int l,int r,int p,int v)
{
if(l == r) cur->sum += v;
else
{
int mid = (l+r)/2;
if(p <= mid) mqery(cur->ls,l,mid,p,v);
else mqery(cur->rs,mid+1,r,p,v);
pushup(cur);
}
return;
}
int main()
{
int n,m;
int i,j,k,l;
scanf("%d%d",&n,&m);
for(i = 1 ; i <= n ; i++)
{
scanf("%d",&ans[i]);
}
Node* head = build(1,n);
for(i = 1 ; i <= m ; i++)
{
scanf("%d%d%d",&k,&j,&l);
if(k == 1)
{
mqery(head,1,n,j,l);
}
else printf("%lld\n",query(head,1,n,j,l));
}
return 0;
}