zoukankan      html  css  js  c++  java
  • 线段树

    线段树是一个用一个数组,想象一棵完全二叉树,赋予其一些意义,数组中存储的信息即为每个节点

    数组中的0 是不用的。

    #define MAX 10000  //待处理的点数,不是树中的节点数
    int tree[MAX * 4];
    void build(int t, int l, int r)
    {
        if (l == r)
        {
            //cin>>tree[t];
            //tree[t]=0;
            //对叶子初始化
            return;
        }
        int mid = l + r >> 1;
        build(t << 1, l, mid);
        build(t << 1 | 1, mid + 1, r);
        //tree[t] = tree[t << 1] + tree[t << 1 | 1];
        //tree[t] = max(tree[t << 1], tree[t << 1 | 1]);
        //对儿子节点递归完可以再用当前点的儿子更新当前点
    }
    //----------------------------------------------------------------------
    void point_update(int t, int l, int r,int x,int y)//将a[x]改为y,点更新
    {
        if (l == r)
        {
            //tree[t] = y;
            return;
        }
        int mid = l + r >> 1;
        if (x <= mid)        //x在左边
            point_update(t << 1, l, mid, x, y);//继续将xy传参
        else if (x > mid)    //x在右边
            point_update(t << 1 | 1, mid + 1, r, x, y);
        //tree[t] = tree[t << 1] + tree[t << 1 | 1];
        //tree[t] = max(tree[t << 1], tree[t << 1 | 1]);
        //对儿子节点递归完可以再用当前点的儿子更新当前点
    }
    //-----------------------------------------------------------------------------------------
    int ans;
    void query(int t, int l, int r, int x, int y)//询问[x,y]的某东西,如最大值。区间查询,需要一个全局变量
    {
        if (x <= l&&y >= r) //当前区间属于[x,y]
        {
            //ans += tree[t];
            return;
        }
        int mid = l + r >> 1;
        if (y <= mid)        //y<=mid说明整个查询区间都在左边
            query(t << 1, l, mid, x, y);//继续将xy传参
        else if (x > mid)    //x>mid说明整个查询区间都在右边
            query(t << 1 | 1, mid + 1, r, x, y);
        else                //区间跨过mid ,则分别往左右儿子递归
        {
            query(t << 1, l, mid, x, y);
            query(t << 1 | 1, mid + 1, r, x, y);
        }
    }
    //-------------------------------------------------------------------------
    //区间更新还需要记录下每个节点打的标记
    struct node
    {
        int num;
        int flag;
    }tre[MAX*4];
    void interval_update(int t, int l, int r, int x, int y,int z)//[x,y]内的数都加z
    {
        if (x <= l&&y >= r) //当前区间属于[x,y],不用再往下走,直接在这里打标记
        {
            tre[t].flag += z;
            return;
        }
        int mid = l + r >> 1;
        if (y <= mid)        //y<=mid说明整个查询区间都在左边
            interval_update(t << 1, l, mid, x, y,z);//继续将xy传参
        else if (x > mid)    //x>mid说明整个查询区间都在右边
            interval_update(t << 1 | 1, mid + 1, r, x, y,z);
        else                //区间跨过mid ,则分别往左右儿子递归
        {
            interval_update(t << 1, l, mid, x, y,z);
            interval_update(t << 1 | 1, mid + 1, r, x, y,z);
        }
    }
    void travel(int t, int l, int r, int f)//f为当前点所以祖先的flag之和
    {
        if (l == r)
        {
            tre[t].num += f;
            tre[t].num += tre[t].flag;//应加上所有祖先的flag和自己的
            return;
        }
        int mid = l + r >> 1;
        travel(t << 1, l, mid,f+tre[t].flag);
        travel(t << 1 | 1, mid + 1, r,f+tre[t].flag);
        //tree[t] = tre[t << 1].num + tre[t << 1 | 1].num;
        //tree[t] = max(tre[t << 1].num, tre[t << 1 | 1].num);
        //对儿子节点递归完可以再用当前点的儿子更新当前点
    }
  • 相关阅读:
    filter的用法
    刚下载好的 vscode 不能运行,一片黑 以及终端不能输入 解决办法
    JS获取光标在input 或 texterea 中下标位置
    JS 数组去重
    字符串操作函数:JSON.parse()、JSON.stringify()、toString 的区别,字符串转数组 str.split(','),数组转字符串String(),以及对象拼接合并Object.assign(),数组拼接合并concat()
    创建标准化工程目录脚本
    configParse模块
    json与api- 天气api 博客词频分析
    文件读写
    os模块、文件压缩 、匹配文件后缀名:fnmatch glob
  • 原文地址:https://www.cnblogs.com/jinmingyi/p/7233134.html
Copyright © 2011-2022 走看看