模板 线段树

线段树建树的时间复杂度为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;
 } 

猜你喜欢

转载自www.cnblogs.com/chuanqiangfan/p/9749362.html
今日推荐