线段树之各类模板

Posted shuaihui

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树之各类模板相关的知识,希望对你有一定的参考价值。

线段树的认识,可以参考哔哔丽丽的视频。

(1)单点曽减,区间求和

飞翔

技术分享图片
#include<stdio.h>
#define lson l,m,rt<<1///左儿子
#define rson m+1,r,rt<<1|1///右儿子
const int maxn = 55555;
int sum[maxn<<2];
void PushUP(int rt)///上一个的值由两个儿子相加
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void build(int l,int r,int rt)///建立
{
    if(l==r)
    {
        scanf("%d",&sum[rt]);///在建立的过程中赋值
        return ;
    }
    int m=(l+r)>>1;
    build(lson);
    build(rson);
    PushUP(rt);
}
void update(int p,int add,int l,int r,int rt)
///p点增减add
{
    if(l==r)
    {
       sum[rt]+=add;
       return ;
    }
    int m=(l+r)>>1;
    if(p<=m)
    update(p,add,lson);
    else
    update(p,add,rson);
    PushUP(rt);
}
///LR区间求和
int query(int L,int R,int l,int r,int rt)
{
    if(L <= l && r<=R)
        return sum[rt];
    int m=(l+r)>>1;
    int ret=0;
    if(L <= m )
    ret+=query(L,R,lson);
    if(R > m)
    ret+=query(L,R,rson);
    return ret;
}
int main( )
{
    int a,b,t,n;
    scanf("%d",&t);
    for(int cas=1 ; cas<=t ; cas++)
    {
        printf("Case %d:\n",cas);
        scanf("%d",&n);
        build(1,n,1);
        char op[10];
        while(scanf("%s",op))
        {
            if(op[0]==E)
            break;
            int a,b;
            scanf("%d%d",&a,&b);
            if(op[0]==S)
            update(a,-b,1,n,1);
            else if(op[0]==Q)
            printf("%d\n",query(a,b,1,n,1));
            else
            update(a,b,1,n,1);
        }
    }
    return 0;
}
View Code

(2)单点替换,区间最值

飞翔

技术分享图片
#include<stdio.h>
#include<algorithm>
using namespace std;

#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1

const int manx = 222222;
int MAX[manx<<2];
void PushUP(int rt)///父亲的值由儿子来得出
{
    MAX[rt]=max(MAX[rt<<1],MAX[rt<<1|1]);
}
void build(int l,int r,int rt)
{
    if ( l==r )
    {
        scanf("%d",&MAX[rt]);
        return ;
    }
    int m = (l+r) >> 1;
    build(lson);
    build(rson);
    PushUP(rt);
}
void update(int p,int sc,int l,int r,int rt)
{   
    ///p点变为sc
    if (l==r)
    {
        MAX[rt]=sc;
        return ;
    }
    int m=(l+r)>>1;
    if(p <= m )
    update(p,sc,lson);
    else
    update(p,sc,rson);
    PushUP(rt);

}
int query(int L,int R,int l,int r,int rt)
{    ///L到R的最大值
    if(L <= l&&r<= R)
        return MAX[rt];
    int m=(l+r)>>1;
    int ret=0;
    if(L<=m)
    ret=max(ret,query(L,R,lson));
    if(R>m)
    ret=max(ret,query(L,R,rson));
    return ret;
}
int main( )
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        build(1,n,1);
        while(m--)
        {
            char op[2];
            int a,b;
            scanf("%s%d%d",op,&a,&b);
            if(op[0]==Q)
            printf("%d\n",query(a,b,1,n,1));
            else
            update(a,b,1,n,1);
        }
    }
    return 0;
}
View Code

 感激这位大牛的模板

以上是关于线段树之各类模板的主要内容,如果未能解决你的问题,请参考以下文章

数据结构——线段树之二(C++)

hdu 1542 线段树之扫描线之面积并

二维线段树之树套树

二维线段树之矩形树 _求解矩阵和问题

线段树之单点更新

进阶线段树之乘法操作