线段树(SegmentTree)基础模板

线段树模板题来源:https://www.lintcode.com/problem/segment-tree-build/description

201.?线段树的构造

/**
 * Definition of SegmentTreeNode:
 * class SegmentTreeNode {
 * public:
 *     int start, end;
 *     SegmentTreeNode *left, *right;
 *     SegmentTreeNode(int start, int end) {
 *         this->start = start, this->end = end;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /*
     * @param start: start value.
     * @param end: end value.
     * @return: The root of Segment Tree.
     */
    SegmentTreeNode * build(int start, int end) {
        // write your code here
        if(start > end) return nullptr;
        auto root = new SegmentTreeNode(start, end);
        if(start < end){
            auto mid = (start + end) / 2;
            root->left = build(start, mid);
            root->right = build(mid+1, end);
        }

        return root;
    }
};

202.?线段树的查询

/**
 * Definition of SegmentTreeNode:
 * class SegmentTreeNode {
 * public:
 *     int start, end, max;
 *     SegmentTreeNode *left, *right;
 *     SegmentTreeNode(int start, int end, int max) {
 *         this->start = start;
 *         this->end = end;
 *         this->max = max;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: The root of segment tree.
     * @param start: start value.
     * @param end: end value.
     * @return: The maximum number in the interval [start, end]
     */
    int query(SegmentTreeNode * root, int start, int end) {
        // write your code here
        auto mid = root->start + (root->end - root->start) / 2;
        if(start <= root->start && root->end <= end) return root->max;
        else if(start > mid) return query(root->right, start, end);
        else if(end <= mid) return query(root->left, start, end);
        else return max(query(root->left, start, mid), query(root->right, mid+1, end));
    }
};

203. 线段树的修改

/**
 * Definition of SegmentTreeNode:
 * class SegmentTreeNode {
 * public:
 *     int start, end, max;
 *     SegmentTreeNode *left, *right;
 *     SegmentTreeNode(int start, int end, int max) {
 *         this->start = start;
 *         this->end = end;
 *         this->max = max;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /**
     * @param root: The root of segment tree.
     * @param index: index.
     * @param value: value
     * @return: nothing
     */
    void modify(SegmentTreeNode * root, int index, int value) {
        // write your code here
        if(root == nullptr || index > root->end || index < root->start) return;
        if(root->start == root->end) {
            root->max = value;
            return ;
        }
        auto mid = root->start + (root->end - root->start) / 2;

        if(index > mid){
            modify(root->right, index, value);
        } else {
            modify(root->left, index, value);
        }
        root->max = max(root->right->max, root->left->max);

    }
};

247. 线段树查询 II

/**
 * Definition of SegmentTreeNode:
 * class SegmentTreeNode {
 * public:
 *     int start, end, count;
 *     SegmentTreeNode *left, *right;
 *     SegmentTreeNode(int start, int end, int count) {
 *         this->start = start;
 *         this->end = end;
 *         this->count = count;
 *         this->left = this->right = NULL;
 *     }
 * }
 */

class Solution {
public:
    /*
     * @param root: The root of segment tree.
     * @param start: start value.
     * @param end: end value.
     * @return: The count number in the interval [start, end]
     */
    int query(SegmentTreeNode * root, int start, int end) {
        // write your code here
        if(root == NULL) return 0;
        if(start <= root->start && root->end <= end) return root->count;
        auto mid = root->start + (root->end - root->start) / 2;
        if(end <= mid) return query(root->left, start, end);
        else if(start > mid) return query(root->right, start, end);
        else return query(root->left, start, mid) + query(root->right, mid + 1, end);
    }
};

248.?统计比给定整数小的数的个数

class Solution {
public:
    /**
     * @param A: An integer array
     * @param queries: The query list
     * @return: The number of element in the array that are smaller that the given integer
     */
    struct SegmentTreeNode {
        int start, end, count;
        SegmentTreeNode* left, *right;
        SegmentTreeNode(int start_, int end_) :
        start(start_), end(end_), count(0), left(nullptr), right(nullptr){}
    };

    SegmentTreeNode* build(int start, int end){
        if(start > end) return nullptr;
        auto root = new SegmentTreeNode(start, end);
        if(start != end){
            auto mid = (start + end) / 2;
            root->left = build(start, mid);
            root->right = build(mid+1, end);
        }

        return root;
    }

    void add(SegmentTreeNode* root, int index, int val){
        auto mid = (root->start + root->end) / 2;
        if(root->start == root->end) {
            root->count += val;
            return;
        }

        if(index > mid){
            add(root->right, index, val);
        } else {
            add(root->left, index, val);
        }

        root->count += val;

    }

    int query(SegmentTreeNode* root, int start, int end){
        if(start <= root->start && root->end <= end) return root->count;
        auto mid = (root->start + root->end) / 2;
        if(start > mid) return query(root->right, start, end);
        else if(end <= mid) return query(root->left, start, end);
        else return query(root->right, mid+1, end) + query(root->left, start, mid);
    }
    vector<int> countOfSmallerNumber(vector<int> &A, vector<int> &queries) {
        // write your code here
        auto root = build(0, 10000);
        for(int i = 0; i < A.size(); i++){
            add(root, A[i], 1);
        }

        vector<int> ret;
        for(int i = 0;  i < queries.size(); i++){
            ret.push_back(query(root, 0, queries[i]-1));
        }

        return ret;
    }
};

249.?统计前面比自己小的数的个数

class Solution {
public:
    /**
     * @param A: an integer array
     * @return: A list of integers includes the index of the first number and the index of the last number
     */
     struct SegmentTreeNode {
        int start, end, count;
        SegmentTreeNode* left, *right;
        SegmentTreeNode(int start_, int end_) :
        start(start_), end(end_), count(0), left(nullptr), right(nullptr){}
    };

    SegmentTreeNode* build(int start, int end){
        if(start > end) return nullptr;
        auto root = new SegmentTreeNode(start, end);
        if(start != end){
            auto mid = (start + end) / 2;
            root->left = build(start, mid);
            root->right = build(mid+1, end);
        }

        return root;
    }

    void add(SegmentTreeNode* root, int index, int val){
        auto mid = (root->start + root->end) / 2;
        if(root->start == root->end) {
            root->count += val;
            return;
        }

        if(index > mid){
            add(root->right, index, val);
        } else {
            add(root->left, index, val);
        }

        root->count += val;

    }

    int query(SegmentTreeNode* root, int start, int end){
        if(start > end) return 0;
        if(start <= root->start && root->end <= end) return root->count;
        auto mid = (root->start + root->end) / 2;
        if(start > mid) return query(root->right, start, end);
        else if(end <= mid) return query(root->left, start, end);
        else return query(root->right, mid+1, end) + query(root->left, start, mid);
    }
    vector<int> countOfSmallerNumberII(vector<int> &A) {
        // write your code here
        auto root = build(0, 10000);
        vector<int> ret;
        for(int i = 0; i < A.size(); i++){
            auto c = query(root, 0, A[i]-1);

            ret.push_back(c);

            add(root, A[i], 1);
        }

        return ret;
    }
};

原文地址:https://www.cnblogs.com/qbits/p/11273469.html

时间: 2024-11-17 12:02:14

线段树(SegmentTree)基础模板的相关文章

线段树 + 区间更新 + 模板 ---- poj 3468

A Simple Problem with Integers Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 59798   Accepted: 18237 Case Time Limit: 2000MS Description You have N integers, A1, A2, ... , AN. You need to deal with two kinds of operations. One type of

HDU1166 线段树(最基础题)

1.写法一: 1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 5 using namespace std; 6 7 int numv[50005<<2]; 8 int A[50005]; 9 10 void builtTree(int o,int l,int r){ 11 if(l==r) { 12 numv[o]=A[l]; 13 return ; 14 } 15 int

hdu1698(线段树区间替换模板)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1698 题意: 第一行输入 t 表 t 组测试数据, 对于每组测试数据, 第一行输入一个 n , 表示钩子有 n 节, 编号为 1 ~ n, 每节钩子的初始价值为 1 , 接下来输入一个 q, 接着 q 行输入, 每行格式为 l, r, x, 表示讲区间 [l, r] 内的钩子价值变成 x , 求最终的总价值: 思路: 线段树区间替换模板 代码: 1 #include <iostream> 2 #

HDU 1166 敌兵布阵 (我的树状数组加线段树点修改模板)

思路:本题因为是点修改,所以我们可以用线段树或者是树状数组了.线段树的基本操作我在我的代码中会具体体现,关键是要理解下面这幅图,具体的思想大家可以去看看其他的资料 线段树AC代码: #include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> using namespace std; #define N 50005 int num

线段树lazytag优化模板

线段树嘛...很基本的一种数据结构啦 lazytag优化能不错的提高效率 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int MAX=1000000; 4 struct pr { 5 int sum; 6 int lazy; 7 int left,right; 8 }tr[MAX+10]; 9 int n; 10 inline int ll(int k) {return 2*k;} 11 inline int rr(int

线段树区间修改模板

本来打算把大白书第三章一口气攻下来的,但是这个线段树也是卡了好久. 不敢过题太快,怕自己走马观花到头来结果什么都不会. 可也不能再拖了,在做题中也许有更多的体会. 模板一:1 L R v 表示区间[L, R]所有元素都加上v2 L R   表示查询区间[L, R]的sum, min, maxsumv[o]的定义为:如果只执行节点o及其子孙节点的中的add操作,节点o对应区间中所有数之和 1 //线段树区间修改 2 //1 L R v 表示区间[L, R]所有元素都加上v 3 //2 L R 表示

线段树经典操作模板(单点更新,替换;区间更新,替换;区间求和求最值)

对于线段树的讲解此篇不再赘述,下面列出线段树应用中最常用的几种操作的代码.(具体题目未贴出,仅供有一定基础者参考代码风格) 另外,注意多组输入要写scanf("%d%d",&n,&m)!=EOF,线段树的题肯定要用c语言的输入输出,要使用字符数组,不用字符串,输入字符的时候要加getchar()吞噬空行.. (1)单点增减,区间求和: #include<iostream> #include<stdio.h> #include<string&

线段树的基础非递归的使用

以下为基础模板 //原数组下标+1=线段树下标//线段树下标+N-1=存储下标 (空出前和尾的一个位置) //原数组下标+N=存储下标 #define maxn 100007int A[maxn],Sum[maxn<<2],add[maxn<<2];int N;//N为扩充元素的个数 int n;//n为原数组元素的个数 void Build(int n){    N=1;    while(N<n+2)       N<<=1;//相同于N=N*2;     f

【luogu P3372 线段树1】模板

线段树的模板题 update区间修改,query区间求和 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #define ll long long 5 #define lson left, mid, rt<<1 6 #define rson mid+1, right, rt<<1|1 7 using namespace std; 8 const int maxn