• 线段树基础


    学长的浅谈线段树~~~

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    const int N = 1e5 + 10;
    int T, n, l, r, cas = 0;
    int f[N * 4]; // f[i]表示i表示的某段区间的和,这种写法的线段树通常需要实际节点数四倍的空间
    char s[5];
    
    /*
            1
        2        3
      4      5      6      7
    
    线段树上对应的节点标号
    对应于4个人的话,每个节点的区间如下:
              [1,4]
        [1,2]        [3,4]
    [1,1]  [2,2] [3,3]  [4,4]
    */
    
    void build(int x, int l, int r)//建树
    {
        //x 节点编号 [l,r]节点表示的区间
        if (l == r) scanf("%d", &f[x]);
        else
        {
            int mid = (l + r) / 2;
            //把[l,r]分为[l,mid]和[mid+1,r]两个区间
            build(x * 2, l, mid);
            build(x * 2 + 1, mid + 1, r);
            f[x] = f[x * 2] + f[x * 2 + 1];
            //区间和就是两个子区间的和相加
        }
    }
    
    int query(int x, int l, int r, int ll, int rr)//询问区间和
    {
        //如果当前节点x代表的区间[l,r]∈[ll,rr]那么直接返回区间和即可。
        //不然递归下去判断左右子区间中是否有[ll,rr]的一部分,并求和。
        if (ll <= l&&r <= rr) return f[x];
        int mid = (l + r) / 2, res = 0;
        if (ll <= mid) res += query(x * 2, l, mid, ll, rr);
        if (rr > mid) res += query(x * 2 + 1, mid + 1, r, ll, rr);
        return res;
    }
    
    void add(int x, int l, int r, int u, int v)//更新结点的值
    {
        f[x] += v; //让某个节点+v相当于所有包含该节点的区间的和都+v
        if (l == r) return;
        int mid = (l + r) / 2;
        //判断在该区间的左子区间还是右子区间
        if (u <= mid) add(x * 2, l, mid, u, v);
        else add(x * 2 + 1, mid + 1, r, u, v);
    }
    
    int main()
    {
        scanf("%d", &T);
        while (T--)
        {
            scanf("%d", &n);
            build(1, 1, n);  //初始化线段树上各节点的值
            printf("Case %d:
    ", ++cas);
            while (scanf("%s", s), s[0] != 'E')
            {
                scanf("%d%d", &l, &r);
                if (s[0] == 'Q') printf("%d
    ", query(1, 1, n, l, r));
                if (s[0] == 'A') add(1, 1, n, l, r);
                if (s[0] == 'S') add(1, 1, n, l, -r);
            }
        }
        return 0;
    }
  • 相关阅读:
    浅谈P2P、P2C 、O2O 、B2C、B2B、 C2C的区别
    用CornerStone配置SVN,HTTP及svn简单使用说明
    Nginx之让用户通过用户名密码认证访问web站点
    linux下php redis扩展安装
    mac下用户用户组命令行操作
    linux下MySQL安装及设置(二)
    linux下MySQL安装及设置
    linux下php的一些问题
    计算多个文档之间的文本相似程度
    提取图像兴趣点
  • 原文地址:https://www.cnblogs.com/iwantstrong/p/6028263.html
Copyright © 2020-2023  润新知