题解 HTOJ P2781 【模板】线段树

题意

即维护一棵线段树,支持单点修改+区间查询。

芝士——线段树

线段树(Segment Tree)是一种树状数据结构,主要用来高效处理区间查询(RMQ)与区间修改问题。

下图就是一棵简单的线段树,每一个节点都是其子节点之和,叶子结点用于存储数值,非叶子结点用于维护区间和。

graph TD
    A["[1,4] sum=10"]-->B["[1,2] sum=3"]
    A-->C["[3,4] sum=7"]
    B-->D["[1,1] sum=1"]
    B-->E["[2,2] sum=2"]
    C-->F["[3,3] sum=3"]
    C-->G["[4,4] sum=4"]

我们可以用一个结构体来存储线段树,但由于二叉树的性质,对于编号为 $n$ 的节点,其左右子节点分别为 $2n$ 和 $2n+1$,我们通常可以用一个数组直接存储线段树(不过需要注意,由于线段树需要维护区间和,所以通常要开 $4$ 倍空间,如果你想省空间而不开 $4$ 倍,就等着 RE 吧 doge)。

由于线段树是基于分治思想实现的,所以可以把单次查询或修改的复杂度降到 $\mathcal{O}(\log n)$。

总时间复杂度:$\mathcal{O}(m\log n)$。

标程

#include<bits/stdc++.h>
#define int long long
using namespace std;
int tree[800005],a[200005];//树要开 4 倍
inline void push_up(int id)//上传,注意不要和lazy_tag的下传搞混
{
    tree[id]=tree[id<<1]+tree[id<<1|1];//更新父节点为子节点之和
}
inline void build(int id,int l,int r)//建树
{
    if(l==r)//到叶子节点了
    {
        tree[id]=a[l];//赋值
        return ;
    }
    else
    {
        int mid=l+r>>1;//分治
        build(id<<1,l,mid);
        build(id<<1|1,mid+1,r);
        push_up(id);
        return ;
    }
}
inline int query(int id,int l,int r,int L,int R)//区间查询
{
    if(L<=l&&R>=r)return tree[id];//完全包含
    int mid=l+r>>1;
    int ans=0;
    if(L<=mid)ans+=query(id<<1,l,mid,L,R);//搜左子树
    if(R>mid)ans+=query(id<<1|1,mid+1,r,L,R);//右子树
    return ans;
}
inline void update(int id,int l,int r,int pos,int x)//单点修改
{
    if(l==r)
    {
        tree[id]=x;
        return;
    }
    int mid=l+r>>1;
    if(pos<=mid)update(id<<1,l,mid,pos,x);
    else update(id<<1|1,mid+1,r,pos,x);
    push_up(id);
}
signed main() 
{
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    build(1,1,n);//除非动态开点,否则都要建树
    while(m--)
    {
        int op,l,r;
        cin>>op>>l>>r;
        if(op==1)
        {
            update(1,1,n,l,r);
        }
        else if(op==2)
        {
            cout<<query(1,1,n,l,r)<<endl;
        }
    }
    return 0;
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇