码迷,mamicode.com
首页 > 其他好文 > 详细

线段树模板

时间:2017-03-05 00:21:16      阅读:196      评论:0      收藏:0      [点我收藏+]

标签:最大   nbsp   else   code   main   btree   下一步   const   val   

自己写的模板,方便以后查看

求最大值的:

#include<iostream>
#include<cstdio>
using namespace std;
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
const int maxn=222222;
int value[maxn<<2];
void PushUp(int rt)
{
    value[rt]=max(value[rt<<1],value[rt<<1|1]);
}
void btree(int l,int r,int rt)
{    //初始为(1,n,1) 
    if(l==r)
    {
        scanf("%d",&value[rt]);
        return ;
    } 
    int m=(l+r)>>1;
    btree(ls);
    btree(rs);
    PushUp(rt);
}
void update(int x,int v,int l,int r,int rt)
{    //初始化为(a,b,1,n,1) 
    if(l==r)
    {
        value[rt]=v;
        return ;
    }
    int m=(l+r)>>1;
    if(x<=m)update(x,v,ls);
    else update(x,v,rs);
    PushUp(rt);
}
int query(int L,int R,int l,int r,int rt)
{    //初始化为(a,b,1,n,1) 
    if(L<=l&&r<=R)return value[rt];
    int m=(l+r)>>1,ans=0;
    if(L<=m)ans=max(ans,query(L,R,ls));
    if(R>m)ans=max(ans,query(L,R,rs));
    return ans;
}
int main()
{
}

求区间和:

#include<iostream>
#include<cstdio>
using namespace std;
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
const int maxn=50005;
int value[maxn<<2],ans;
void PushUp(int rt)
{
    value[rt]=value[rt<<1]+value[rt<<1|1];
}
void btree(int l,int r,int rt)
{    //初始为(1,n,1) 
    if(l==r)
    {
        scanf("%d",&value[rt]);
        return ;
    } 
    int m=(l+r)>>1;
    btree(ls);
    btree(rs);
    PushUp(rt);
}
void update(int x,int v,int l,int r,int rt)
{    //初始化为(a,b,1,n,1) 
    if(l==r)
    {
        value[rt]+=v;
        return ;
    }
    int m=(l+r)>>1;
    if(x<=m)update(x,v,ls);
    else update(x,v,rs);
    PushUp(rt);
}
void query(int L,int R,int l,int r,int rt)
{    //初始化为(a,b,1,n,1) 
    if(L<=l&&r<=R)
    {
        ans+=value[rt];
        return ;
    }
    if(l==r)return; 
    int m=(l+r)>>1;
    if(R<=m)query(L,R,ls);
    else if(L>m)query(L,R,rs);
         else
         {
             query(L,R,ls);
             query(L,R,rs);
          } 
           
}
int main()
{
    return 0;
}

区间更新的:

#include<iostream>
#include<cstdio> 
using namespace std;
#define ll long long
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
const int maxn=100005; 
ll value[maxn<<2],add[maxn<<2];
void PushUp(int rt)
{
    value[rt]=value[rt<<1]+value[rt<<1|1];
}
void PushDown(int rt,int m)//m是当前节点区间的范围  
{          //例如1-5  右儿子4-5,左儿子1-3  m=5,m>>1=2刚好是右儿子区间范围,m-(m>>1)=3为左儿子区间范围
    if(add[rt])//向下更新子节点 
    {
        add[rt<<1]+=add[rt];//更新左儿子的lazy标记
        add[rt<<1|1]+=add[rt];//右儿子
        value[rt<<1]+=(m-(m>>1))*add[rt];//更新左儿子的权值,应该乘上左儿子区间(r-l+1)
        value[rt<<1|1]+=(m>>1)*add[rt];//应该乘右儿子区间范围
        add[rt]=0;
    }
}
void btree(int l,int r,int rt)
{   //初始化1,n,1 
    add[rt]=0;
    if(l==r)
    {
        scanf("%lld",&value[rt]);
        return ;
    }
    int m=(l+r)>>1;
    btree(ls);
    btree(rs);
    PushUp(rt);
}
void update(int L,int R,int c,int l,int r,int rt)
{    //初始化a,b,c,1,n,1 
    if(L<=l&&r<=R)//给定区间大于现有区间 
    {
        add[rt]+=c;//标记加上 
        value[rt]+=(ll)c*(r-l+1);//更新当前节点 
        return ;
    }
    PushDown(rt,r-l+1);//向下更新子节点因为下一步要使用子节点 
    int m=(l+r)>>1;
    if(L<=m)update(L,R,c,ls);
    if(R>m)update(L,R,c,rs);
    PushUp(rt);//向上关系父节点 
} 
ll query(int L,int R,int l,int r,int rt)
{   //初始化为a,b,1,n,1 
    if(L<=l&&r<=R)return value[rt];
    PushDown(rt,r-l+1);
    int m=(l+r)>>1;
    ll ans=0;
    if(L<=m)ans+=query(L,R,ls);
    if(R>m)ans+=query(L,R,rs);
    return ans;
}
int main()
{
}

 

线段树模板

标签:最大   nbsp   else   code   main   btree   下一步   const   val   

原文地址:http://www.cnblogs.com/acjiumeng/p/6503065.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!