一些线段树板子c++

区间修改(change to),区间求最小值

//此板子适合修改值为正数时使用,否则需要修改初始化的tr[i].tag;
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=1000010;
int t;
int n,m,q;
struct segtree{
    int l,r;//这个节点的范围
    int val;
    int tag;
}tr[maxn*4];
void build(int root,int l,int r)//根节点为1,范围从1-n
{
    tr[root].l=l;
    tr[root].r=r;
    tr[root].tag=-1;//修改值若为负数则要修改,tag的值应在修改范围之外
    if(l==r)
    {
        tr[root].val=INT_MAX;//初始值
        return;
    }
    int mid=(l+r)/2;
    build(root*2,l,mid);
    build(root*2+1,mid+1,r);
    tr[root].val=min(tr[root*2].val,tr[root*2+1].val);
}
void spread(int p)
{
    if(tr[p].tag!=-1)
    {
        tr[p*2].val=tr[p].tag;
        tr[p*2+1].val=tr[p].tag;
        tr[p*2].tag=tr[p].tag;
        tr[p*2+1].tag=tr[p].tag;
        tr[p].tag=-1;
    }
}
void update(int root,int l,int r,int x)
{
    if(l<=tr[root].l&&r>=tr[root].r)
    {
        tr[root].val=x;
        tr[root].tag=x;
        return;
    }
    spread(root);
    int mid=(tr[root].l+tr[root].r)>>1;
    if(l<=mid)
        update(root*2,l,r,x);
    if(r>mid)
        update(root*2+1,l,r,x);
    tr[root].val=min(tr[root*2].val,tr[root*2+1].val);
}
int getmin(int root,int l,int r)//单点更新下的
{
    if(l<=tr[root].l&&r>=tr[root].r)
        return tr[root].val;
    spread(root);
    int mid=(tr[root].l+tr[root].r)>>1;
    int ans=INT_MAX;
    if(l<=mid)
        ans=min(ans,getmin(root*2,l,r));
    if(r>mid)
        ans=min(ans,getmin(root*2+1,l,r));
    return ans;
}

区间修改(change to),区间求和

#include<bits/stdc++.h>
#define int long long //防止爆int
int t;
int n,m,q;
int a[maxn];
struct segtree{
    int l,r;
    int val;
    int tag;
}tr[maxn*4];
void build(int root,int l,int r)
{
    tr[root].l=l;
    tr[root].r=r;
    tr[root].tag=inf;//tag初始化为最大值
    if(l==r)
    {
        tr[root].val=a[l];//初始值
        return;
    }
    int mid=(l+r)/2;
    build(root*2,l,mid);
    build(root*2+1,mid+1,r);
    tr[root].val=tr[root*2].val+tr[root*2+1].val;//统计区间和
}
void spread(int p)
{
    if(tr[p].tag!=inf)
    {
        tr[p*2].val=tr[p].tag*(tr[p*2].r-tr[p*2].l+1);
        tr[p*2+1].val=tr[p].tag*(tr[p*2+1].r-tr[p*2+1].l+1);
        tr[p*2].tag=tr[p].tag;
        tr[p*2+1].tag=tr[p].tag;
        tr[p].tag=inf;
    }
}
void update(int root,int l,int r,int x)
{
    if(l<=tr[root].l&&r>=tr[root].r)
    {
        tr[root].val=x*(tr[root].r-tr[root].l+1);
        tr[root].tag=x;
        return;
    }
    spread(root);
    int mid=(tr[root].l+tr[root].r)>>1;
    if(l<=mid)
        update(root*2,l,r,x);
    if(r>mid)
        update(root*2+1,l,r,x);
    tr[root].val=tr[root*2].val+tr[root*2+1].val;
}
int getsum(int root,int l,int r)//单点更新下的
{
    if(l<=tr[root].l&&r>=tr[root].r)
        return tr[root].val;
    spread(root);
    int mid=(tr[root].l+tr[root].r)>>1;
    int ans=0;
    if(l<=mid)
        ans+=getsum(root*2,l,r);
    if(r>mid)
        ans+=getsum(root*2+1,l,r);
    return ans;
}

最常用,区间加减,区间查询(sum)

#include<bits/stdc++.h>
#define int long long //防止爆int
int t;
int n,m,q;
int a[maxn];
struct segtree{
    int l,r;
    int val;
    int tag;
}tr[maxn*4];
void build(int root,int l,int r)
{
    tr[root].l=l;
    tr[root].r=r;
    tr[root].tag=0;//tag为0则不用修改
    if(l==r)
    {
        tr[root].val=a[l];//初始值
        return;
    }
    int mid=(l+r)/2;
    build(root*2,l,mid);
    build(root*2+1,mid+1,r);
    tr[root].val=tr[root*2].val+tr[root*2+1].val;//统计区间和
}
void spread(int p)
{
    if(tr[p].tag!=0)
    {
        tr[p*2].val+=tr[p].tag*(tr[p*2].r-tr[p*2].l+1);
        tr[p*2+1].val+=tr[p].tag*(tr[p*2+1].r-tr[p*2+1].l+1);
        tr[p*2].tag+=tr[p].tag;
        tr[p*2+1].tag+=tr[p].tag;
        tr[p].tag=0;
    }
}
void update(int root,int l,int r,int x)
{
    if(l<=tr[root].l&&r>=tr[root].r)
    {
        tr[root].val+=x*(tr[root].r-tr[root].l+1);
        tr[root].tag+=x;
        return;
    }
    spread(root);
    int mid=(tr[root].l+tr[root].r)>>1;
    if(l<=mid)
        update(root*2,l,r,x);
    if(r>mid)
        update(root*2+1,l,r,x);
    tr[root].val=tr[root*2].val+tr[root*2+1].val;
}
int getsum(int root,int l,int r)//单点更新下的
{
    if(l<=tr[root].l&&r>=tr[root].r)
        return tr[root].val;
    spread(root);
    int mid=(tr[root].l+tr[root].r)>>1;
    int ans=0;
    if(l<=mid)
        ans+=getsum(root*2,l,r);
    if(r>mid)
        ans+=getsum(root*2+1,l,r);
    return ans;
}

区间加减,区间最值查询(min)

#include<bits/stdc++.h>
#define int long long //防止爆int
using namespace std;
const int maxn=1000010;
const int inf=0x3f3f3f3f;
int t;
int n,m,q;
struct segtree{
    int l,r;
    int val;
    int tag;
}tr[maxn*4];
void build(int root,int l,int r)
{
    tr[root].l=l;
    tr[root].r=r;
    tr[root].tag=0;//tag为0则不用修改
    if(l==r)
    {
        tr[root].val=0;//初始值
        return;
    }
    int mid=(l+r)/2;
    build(root*2,l,mid);
    build(root*2+1,mid+1,r);
    tr[root].val = min(tr[root * 2].val, tr[root * 2 + 1].val);
}
void spread(int p)
{
    if(tr[p].tag!=0)
    {
        tr[p * 2].val += tr[p].tag;
        tr[p * 2 + 1].val += tr[p].tag;
        tr[p * 2].tag += tr[p].tag;
        tr[p * 2 + 1].tag += tr[p].tag;
        tr[p].tag = 0;
    }
}
void update(int root,int l,int r,int x)
{
    if(l<=tr[root].l&&r>=tr[root].r)
    {
        tr[root].val+=x;
        tr[root].tag+=x;
        return;
    }
    spread(root);
    int mid=(tr[root].l+tr[root].r)>>1;
    if(l<=mid)
        update(root*2,l,r,x);
    if(r>mid)
        update(root*2+1,l,r,x);
    tr[root].val=min(tr[root*2].val,tr[root*2+1].val);
}
int getsum(int root,int l,int r)//单点更新下的
{
    if(l<=tr[root].l&&r>=tr[root].r)
        return tr[root].val;
    spread(root);
    int mid=(tr[root].l+tr[root].r)>>1;
    int ans=inf;
    if(l<=mid)
        ans=min(ans,getsum(root*2,l,r));
    if(r>mid)
        ans=min(ans,getsum(root*2+1,l,r));
    return ans;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值