zoukankan      html  css  js  c++  java
  • 线段树模板加模板题POJ3468

    POJ - 3468

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

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

    #include<iostream>
    #include<cstdio>
    #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
    ",query(1,l,r));
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    LeetCode链表解题模板
    c++中的new、operator new、placement new
    树的前序、中序、后续、层次遍历的递归和非递归解法
    c++Volatile关键词
    南大算法设计与分析课程OJ答案代码(5)--割点与桥和任务调度问题
    c++右值引用以及使用
    c++选择重载函数
    从4行代码看右值引用
    被遗忘的C结构体打包技术
    南大算法设计与分析课程OJ答案代码(4)--变位词、三数之和
  • 原文地址:https://www.cnblogs.com/Zzqf/p/11628663.html
Copyright © 2011-2022 走看看