• 线段树


    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1166

    #include<iostream>
    #include<vector>
    #include<algorithm>
    #include<string>
    using namespace std;
    #define intervalNum 51000
    class node{
    public:
        int maximum;
        int minimum;
        int sum;
        int start;
        int end;
        void setVal(int _maximum,int _minimum,int _sum){
            maximum = _maximum;
            minimum = _minimum;
            sum = _sum;
        }
        bool isLeaf(){
            if (start == end){
                return true;
            }
            else{
                return false;
            }
        }
        bool compare(int index){
            if (index>=start&&index<=end){
                return true;
            }
            else{
                return false;
            }
        }
        void setRange(int _start,int _end){
            start = _start;
            end = _end;
        }
        node(int _maximum, int _minimum, int _sum){
            maximum = _maximum;
            minimum = _minimum;
            sum = _sum;
        }
        node(){
    
        }
    };
    //递归建立线段树
    //tree:线段树的数组
    //root:根节点
    //start:左区间
    //end: 右区间
    void buildSegTree(node tree[],int root,int start,int end){
        int mid = (start + end) / 2;
        int lChild = root * 2;
        int rChild = lChild + 1;
        tree[root].setRange(start, end);
        if (start==end){
            int val;
            scanf("%d", &val);
            tree[root].setVal(val,val,val);
            return;
        }
        buildSegTree(tree,root*2,start,mid);
        buildSegTree(tree, root * 2+1, mid+1,end);
        tree[root].setVal(max(tree[lChild].maximum,tree[rChild].maximum),min(tree[lChild].minimum,tree[rChild].minimum),tree[lChild].sum + tree[rChild].sum);
    }
    //单点更新
    //tree:线段树数组
    //root:根节点
    //index: 更新的区间
    //addVal:变化的数值:newValue=oldValue+fluctuation
    void updateNode(node tree[],int root,int index,int fluctuation){
        if (tree[root].isLeaf()){
            int newVal = tree[root].sum + fluctuation;
            tree[root].setVal(newVal, newVal, newVal);
            return;
        }
        int lChild = root * 2;
        int rChild = root * 2 + 1;
        if (tree[lChild].compare(index)){
            updateNode(tree, lChild, index, fluctuation);
        }
        else{
            updateNode(tree, rChild, index, fluctuation);
        }
        tree[root].setVal(max(tree[lChild].maximum, tree[rChild].maximum), min(tree[lChild].minimum, tree[rChild].minimum), tree[lChild].sum + tree[rChild].sum);
    }
    //查询区间和
    //tree:线段树数组
    //root:根节点
    //start:查询开始
    //end::查询结束
    int querySum(node tree[],int root,int start,int end){
        if (tree[root].start==start&&tree[root].end==end){
            return tree[root].sum;
        }
        int lChild = root * 2;
        int rChild = lChild + 1;
        if (start<=tree[lChild].end&&end >= tree[rChild].start){
            return querySum(tree, lChild, start, tree[lChild].end) + querySum(tree, rChild, tree[rChild].start, end);
        }
        else if (start>=tree[lChild].start&&end <= tree[lChild].end){
            return querySum(tree, lChild, start, end);
        }
        else if (start >= tree[rChild].start&&end <= tree[rChild].end){
            return querySum(tree, rChild, start, end);
        }
        
    }
    //查询区间最大值
    //tree:线段树数组
    //root:根节点
    //start:查询开始
    //end::查询结束
    int queryMax(node tree[], int root, int start, int end){
        if (tree[root].start == start&&tree[root].end == end){
            return tree[root].maximum;
        }
        int lChild = root * 2;
        int rChild = lChild + 1;
        int mid = (start + end) / 2;
        if (start <= tree[lChild].end&&end >= tree[rChild].start){
            return max(queryMax(tree, lChild, start, tree[lChild].end), queryMax(tree, rChild, tree[rChild].start, end));
        }
        else if (start >= tree[lChild].start&&end <= tree[lChild].end){
            return queryMax(tree, lChild, start, end);
        }
        else if (start >= tree[rChild].start&&end <= tree[rChild].end){
            return queryMax(tree, rChild, start, end);
        }
    }
    //查询区间最小值
    //tree:线段树数组
    //root:根节点
    //start:查询开始
    //end::查询结束
    int queryMin(node tree[], int root, int start, int end){
        if (tree[root].start == start&&tree[root].end == end){
            return tree[root].maximum;
        }
        int lChild = root * 2;
        int rChild = lChild + 1;
        int mid = (start + end) / 2;
        if (start <= tree[lChild].end&&end >= tree[rChild].start){
            return min(queryMin(tree, lChild, start, tree[lChild].end), queryMin(tree, rChild, tree[rChild].start, end));
        }
        else if (start >= tree[lChild].start&&end <= tree[lChild].end){
            return queryMin(tree, lChild, start, end);
        }
        else if (start >= tree[rChild].start&&end <= tree[rChild].end){
            return queryMin(tree, rChild, start, end);
        }
    }
    int main(){
        node tree[intervalNum * 4]; //大小为区间数的四倍
        int T = -1;
        int N = -1;
        vector<int> result;
        scanf("%d", &T);
        scanf("%d", &N);
        buildSegTree(tree, 1, 1, N);
        for (int i = 1; i <= T; ++i){
            while (true){
                string cmd;
                int argu1, argu2;
                cin >> cmd;
                if (cmd == "Add"){
                    cin>> argu1 >> argu2;
                    updateNode(tree, 1, argu1, argu2);
                }
                else if(cmd=="Sub"){
                    cin >> argu1 >> argu2;
                    updateNode(tree, 1, argu1, -argu2);
                }
                else if (cmd == "Query"){
                    cin >> argu1 >> argu2;
                    result.push_back(querySum(tree, 1, argu1,argu2));
                }
                else if (cmd == "End"){
                     cout <<"case " << i<<":"<<endl;
                    for (int i = 0; i < result.size(); ++i){
                        cout << result[i] << endl;
                    }
                    result.clear();
                    break;
                }
            }
        }
        system("pause");
    }
  • 相关阅读:
    -webkit-line-clamp 多行文字溢出...
    整理一些知识碎片...
    localstorage sessionstorage和cookie的区别
    数据结构 --- Set
    Iterator(遍历器)
    ES6数组方法 -- reduce()
    ES6 -- 展开运算符
    Centos7 + Oracel 18c
    Mysql 查询返回大量数据导致内存溢出
    github的安装和使用
  • 原文地址:https://www.cnblogs.com/codeDog123/p/6656977.html
Copyright © 2020-2023  润新知