线段树模板加模板题POJ3468

POJ - 3468

整理了个新的线段树的模板,暑期集训的时候学长给的模板,每个节点单单存了自己所要维护的内容,还是少了点。导致在写pushdown的时候,len我会有点难写。所以就整理个新的模板。

每个节点还存了l,r,lazy,len,写起来思路清晰多了。

#include
#include
#define lson (rt << 1)
#define rson (rt << 1 | 1)
#define Lson lson, l, mid
#define Rson rson, mid + 1, r
typedef long long ll;
const int INF=0x3f3f3f3f;
const int maxn=1e5+7;
using namespace std;
struct node
{
    ll val;//
    int len;//长度
    ll lazy;//标记
    int l,r;//左右端点
}tree[maxn<<2];

ll arr[maxn];

int n,m;

void build(int rt,int l,int r)  //建树
{
    tree[rt].lazy=0;
    tree[rt].l=l;tree[rt].r=r;
    tree[rt].len=r-l+1;
    if (l==r) tree[rt].val=arr[l];//到达树端点,给val赋值
    else
    {
        int mid=(l+r)/2;
        build(Lson);
        build(Rson);
        tree[rt].val=tree[lson].val+tree[rson].val;
    }
}

void pushdown(int rt)  //向下传递lazy标记
{
    if (tree[rt].lazy)
    {
        tree[lson].lazy+=tree[rt].lazy;
        tree[rson].lazy+=tree[rt].lazy;
        tree[lson].val+=tree[lson].len*tree[rt].lazy;
        tree[rson].val+=tree[rson].len*tree[rt].lazy;
        tree[rt].lazy=0;
    }
}

void add(int rt,int id,ll addval)  //单点更新
{
    if (tree[rt].l==tree[rt].r)
    {
        tree[rt].val+=addval;
        return;
    }
    else
    {
        int mid=(tree[rt].l+tree[rt].r)/2;
        if (id<=mid) add(lson,id,addval);
        else add(rson,id,addval);
        tree[rt].val=tree[lson].val+tree[rson].val;
    }
}

ll query(int rt,int l,int r)  //计算区间和
{
    if (tree[rt].l>=l&&tree[rt].r<=r)
        return tree[rt].val;
    if (tree[rt].l>r||tree[rt].r<l)
        return 0;
    pushdown(rt);
    return query(lson,l,r)+query(rson,l,r);
}

void update(int rt,int l,int r,ll addval)  //区间更新
{
    ll mid;
    if (tree[rt].l>=l&&tree[rt].r<=r)
    {
        tree[rt].lazy+=addval;
        tree[rt].val+=tree[rt].len*addval;
        return;
    }
    if (tree[rt].l>r||tree[rt].r<l)
        return;
    pushdown(rt);
    update(lson,l,r,addval);
    update(rson,l,r,addval);
    tree[rt].val=tree[lson].val+tree[rson].val;
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n;i++)
    {
        scanf("%lld",&arr[i]);
    }
    build(1,1,n);
    for (int i=1;i<=m;i++)
    {
        char s[10];
        scanf("%s",s);
        int l,r;
        ll x;
        if (s[0]=='C')
        {

            scanf("%d%d%lld",&l,&r,&x);
            update(1,l,r,x);
        }
        else
        {
            scanf("%d%d",&l,&r);
            printf("%lld\n",query(1,l,r));
        }
    }
    return 0;
}
View Code

 

你可能感兴趣的:(线段树模板加模板题POJ3468)