• 点更新线段树模板


    点更新线段树

    对一列数,对每次询问输出对应区间的和,每次修改只修改一个数的值。。。

    定义:

    struct tree
    {
        int l,r;//记录代表的区间
        int sum;//代表区间的和
    }


    由于线段树还是相对比较平衡的,所以可以使用数组t来存储这棵树,
    对与某个节点i,t[i*2]就是左子树,t[i*2+1]就是右子树
    建树:线段树的思想是每个节点记录区间的信息,某点区间1~n,则1~n/2为其左子树,n/2+1~n为其右子树,每次建立子树方法相同,可以递归建树。。。
    至于询问,如果询问区间并不是树上某个确切的节点,就拆分开落到其子树上,追究到底还是递归。。
    加和,现在是对点加和还是比较容易的,回溯时将每个节点的sum值更新即可。。。

    tree数组开的大小一般是数据数组a大小的4倍

    模板的注意事项

    一开始数据读入a数组中,需要的话请自行更改成其他名字。

    buildtree(id,l,r)   初次调用id一般是头结点0,l与r是构造的范围,初次调用为1~n或者0~n-1,注意buildtree时要求a中有值,如果建立一个空树,需要把a清零,或者把函数中a[i]出现的地方改为0

    update(id,s,w)   初次调用id一般是头结点0,s为需要修改的位置的下标,w为要修改成的值

    sum(id,l,r)         初次调用id一般是头结点0,求下标l到r的和的值。

    线段树还可以求最大最小值,把求和改成max()或者min()即可。

    模板:

    struct tree
    {
        int l,r;
        int s;
    }t[400001];
    int a[100001];
    int p,b,l,r;
    
    int calc(int x,int y)//加和运算,如果求最大最小值,更改这里就可以了。 
    {
        return x+y;
    }
    
    void buildtree(int id,int l,int r,int *a)
    {
        if (l==r)
        {
            t[id].l=l;
            t[id].r=r;
            t[id].s=a[l];
        } else
        {
            int mid=(l+r)/2;
            buildtree(id*2,l,mid,a);
            buildtree(id*2+1,mid+1,r,a);
            t[id].l=l;
            t[id].r=r;
            t[id].s=calc(t[id*2].s,t[id*2+1].s);
        }
    }
    
    void update(int id,int s,int w)//s点加上w,可以根据需要改成赋值号 
    {
        if (t[id].l==t[id].r)
        {
            t[id].s+=w;
        } else
        {
            int mid=(t[id].l+t[id].r)/2;
            if (s<=mid) update(id*2,s,w);
            else update(id*2+1,s,w);
            t[id].s=calc(t[id*2].s,t[id*2+1].s);
        }
    }
    
    int sum(int id,int l,int r)
    {
        if ((t[id].l==l)&&(t[id].r==r))
        {
            return t[id].s;
        } else
        {
            int mid=(t[id].l+t[id].r)/2;
            if (r<=mid) return sum(id*2,l,r);
            if (mid<l) return sum(id*2+1,l,r);
            return calc(sum(id*2,l,mid),sum(id*2+1,mid+1,r));
        }
    }
  • 相关阅读:
    二叉搜索树
    splay模板
    树状数组模板
    K尾相等数
    寻找最大数
    布线问题(最小生成树)
    开心的小明
    独木舟上的旅行(二)
    The Triangle(记忆化搜索)
    喷水装置(二)
  • 原文地址:https://www.cnblogs.com/zhyfzy/p/4293988.html
Copyright © 2020-2023  润新知