---
# System prepended metadata

title: segment tree線段樹

---

# segment tree線段樹

## 模板
```cpp=
#pragma GCC optimize("Ofast","inline","-ffast-math","no-stack-protector")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
#define inf 1e9
#define maxn 100005
#define mod 1000000007

int arr[maxn];
int tree[maxn*4];

//建樹
void build(int node,int start,int end){
    if(start==end){
        tree[node]=arr[start];
    }
    else{
        int mid=(start+end)/2;
        int left_node=2*node+1;
        int right_node=2*node+2;

        build(left_node,start,mid);
        build(right_node,mid+1,end);
        tree[node]=tree[left_node]+tree[right_node];
    }
}

//更新樹上的某一點
void update(int node,int start,int end,int idx,int val){
    if(start==end){
        arr[idx]=val;
        tree[node]=val;
    }
    else{
        int mid=(start+end)/2;
        int left_node=2*node+1;
        int right_node=2*node+2;
        if(idx>=start and idx<=mid){
            update(left_node,start,mid,idx,val);
        }
        else{
            update(right_node,mid+1,end,idx,val);   
        }
        tree[node]=tree[left_node]+tree[right_node];
    }
}

//L到R的和
int query(int node,int start,int end,int L,int R){
    if(R<start or L>end){
        return 0;
    }
    else if(start==end){
        return tree[node];
    }
    else{
        int mid=(start+end)/2;
        int left_node=2*node+1;
        int right_node=2*node+2;
        int sum_left=query(left_node,start,mid,L,R);
        int sum_right=query(right_node,mid+1,end,L,R);
        return sum_left+sum_right;
    }
}

signed main(){

    ios::sync_with_stdio(0);
    cin.tie(0);

}
```

## 範例練習
CSES:Static Range Sum Queries
https://cses.fi/problemset/task/1646
```cpp=
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define endl "\n"
#define inf 1e9
#define maxn 10000005
 
int arr[maxn];
int tree[maxn];
void build(int node,int start,int end){
    if(start==end){
        tree[node]=arr[start];
    }
    else{
        int mid=(start+end)/2;
        int left_node=2*node+1;
        int right_node=2*node+2;
        build(left_node,start,mid);
        build(right_node,mid+1,end);
        tree[node]=tree[left_node]+tree[right_node];
    }
}
 
int query(int node,int start,int end,int left,int right){
    if(right<start or left>end){
        return 0;
    }
    else if(left<=start and end<=right){
        return tree[node];
    }
    else if(start==end){
        return tree[node];
    }
    else{
        int mid=(start+end)/2;
        int left_node=2*node+1;
        int right_node=2*node+2;
        int sum_left=query(left_node,start,mid,left,right);
        int sum_right=query(right_node,mid+1,end,left,right);
        return sum_left+sum_right;
    }
}
 
void update(int node,int start,int end,int index,int value){
    if(start==end){
        arr[index]=value;
        tree[node]=value;
    }
    else{
        int mid=(start+end)/2;
        int left_node=2*node+1;
        int right_node=2*node+2;
        if(index>=start and index<=mid){
            update(left_node,start,mid,index,value);
        }
        else{
            update(right_node,mid+1,end,index,value);
        }
        tree[node]=tree[left_node]+tree[right_node];
    }
}
 
 
signed main(){
    
    ios::sync_with_stdio(0);
    cin.tie(0);
 
    int n,q;
    cin>>n>>q;
    for(int i=1;i<=n;i++){
        cin>>arr[i];
    }
    build(1,1,n);
    for(int i=1;i<=q;i++){
        int l,r;
        cin>>l>>r;
        cout<<query(1,1,n,l,r)<<endl;
    }
}
```