ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【模板】线段树(&离散化)

2022-02-20 08:34:30  阅读:125  来源: 互联网

标签:right const int 线段 tree mid 离散 id 模板


#include<bits/stdc++.h>
using namespace std;
const int the_size = 262144;
int in[the_size], n, m, s, e, v, ans;
char judge;
struct TREE{                                                                //结构体-树
    int left, right;
    int maxn, sumn, minn;
    int lid, rid;
    int lazy;
    //other information;
} tree[the_size]; int cnt;
int x = 0, f = 1; char c;
inline int g() {                                                            //快读;
    x = 0; f = 1; c = getchar();
    for(;(c > '9'||c < '0')&&c != '-';c = getchar());
    if(c == '-') { f = -1; c = getchar();}
    for(;c >= '0'&&c <= '9';c = getchar()) x = (x<<3)+(x<<1)+c-'0';
    return x*f;
}//快读;
inline void discrete(int *a,const int k) {                                  //离散化;
    int data[the_size];
    for(register int i = 1;i <= k;i++) data[i] = a[i];
    sort(data+1,data+k+1);
    int cc = unique(data+1,data+k+1)-data;
    for(register int i = 1;i <= k;i++) {
        a[i] = lower_bound(data+1,data+cc,a[i])-data;
    }
    return;
}//离散化;
inline void construct(const int id,const int l,const int r) {               //建树;
    tree[id].left = l; tree[id].right = r;
    if(l == r) {
        tree[id].minn = in[l];
        tree[id].maxn = in[l];
        tree[id].sumn = in[l];
        return;
    }//if is leaf;
    int mid = (l+r)/2;      //the middle point;
    tree[id].lid = ++cnt; tree[id].rid = ++cnt;
    construct(tree[id].lid,l,mid);  //build the left son_tree;
    construct(tree[id].rid,mid+1,r); //build the right son_tree;
    tree[id].minn = min(tree[tree[id].lid].minn,tree[tree[id].rid].minn);   //preserve the minn;
    tree[id].sumn = tree[tree[id].lid].sumn+tree[tree[id].rid].sumn;        //preserve the sumn;
    tree[id].maxn = max(tree[tree[id].lid].maxn,tree[tree[id].rid].maxn);   //preserve the maxn;
    return;
}//建树;
inline void pushdown(const int id) {                                        //下放;
    tree[tree[id].lid].lazy += tree[id].lazy;//perserve the sign of pushdown(lazy);
    tree[tree[id].rid].lazy += tree[id].lazy;//perserve the sign of pushdown(lazy);
    tree[tree[id].lid].sumn += tree[id].lazy*(tree[tree[id].lid].right-tree[tree[id].lid].left+1);//preserve the sumn;
    tree[tree[id].rid].sumn += tree[id].lazy*(tree[tree[id].rid].right-tree[tree[id].rid].left+1);//preserve the sumn;
    tree[id].lazy = 0;
    return;
}//下放;
inline void pushup(const int id) {                                          //上传;
    tree[id].sumn = tree[tree[id].lid].sumn+tree[tree[id].rid].sumn;        
    tree[id].maxn = max(tree[tree[id].lid].maxn,tree[tree[id].rid].maxn);   
    tree[id].minn = min(tree[tree[id].lid].minn,tree[tree[id].rid].minn);   
    return;
}//上传;
inline void update(const int id,const int l,const int r,const int val) {    //区间修改;
    if(tree[id].left == l&&tree[id].right == r) {
        tree[id].lazy += val;
        tree[id].sumn += val*(tree[id].right-tree[id].left+1);
        tree[id].maxn += val;
        tree[id].minn += val;
        return;
    }//if is leaf;
    pushdown(id);//pushdown;
    int mid = (tree[id].left+tree[id].right)>>1;    //find the middle point;
    if(r <= mid) update(tree[id].lid,l,r,val);      //if is left son_tree;
    else if(l > mid) update(tree[id].rid,l,r,val);  //if is right son_tree;
    else {  
        update(tree[id].lid,l,mid,val); 
        update(tree[id].rid,mid+1,r,val);   //zone discover;
    }
    pushup(id);
    return;
}//区间修改;
inline void modify(const int id,const int sec,const int val) {              //修改单点值;
    if(tree[id].left == tree[id].right) {
        tree[id].sumn = tree[id].maxn = val;
        return;
    }//if is leaf;
    int mid = (tree[id].left+tree[id].right)>>1;        //the middle point;
    modify(sec <= mid ? tree[id].lid : tree[id].rid,sec,val);//
    tree[id].sumn = tree[tree[id].lid].sumn + tree[tree[id].rid].sumn;      //preserve the sumn;
    tree[id].maxn = max(tree[tree[id].lid].maxn,tree[tree[id].rid].maxn);   //preserve the maxn;
    return;
}//修改单点值;
inline int query(const int id,const int l,const int r) {                    //区间求和;
    if(tree[id].left == l&&tree[id].right == r) {
        return tree[id].sumn;//if is leaf;
    }
    pushdown(id);
    int mid = (tree[id].left+tree[id].right)>>1;//find the middle point;
    if(r <= mid) return query(tree[id].lid,l,r);    //if is left son_tree;
    else if(l > mid) return query(tree[id].rid,l,r);    //if is right son_tree;
    else return query(tree[id].lid,l,mid)+query(tree[id].rid,mid+1,r);
}//区间求和;
inline int majority(const int id,const int l,const int r) {                 //区间求最大值;
    if(tree[id].left == l&&tree[id].right == r) {
        return tree[id].maxn;//if is leaf;
    }
    pushdown(id);
    int mid = (tree[id].left+tree[id].right)>>1;//find the middle point;
    if(r <= mid) return majority(tree[id].lid,l,r); //if is left son_tree;
    else if(l > mid) return majority(tree[id].rid,l,r); //if is right son_tree;
    else return max(majority(tree[id].lid,l,mid),majority(tree[id].rid,mid+1,r));
}//区间求最大值;
inline int minority(const int id,const int l,const int r) {                 //区间求最小值;
    if(tree[id].left == l&&tree[id].right == r) {
        return tree[id].minn;//if is leaf;
    }
    pushdown(id);
    int mid = (tree[id].left+tree[id].right)>>1;//find the middle point;
    if(r <= mid) return minority(tree[id].lid,l,r); //if is left son_tree;
    else if(l > mid) return minority(tree[id].rid,l,r); //if is right son_tree;
    else return min(minority(tree[id].lid,l,mid),minority(tree[id].rid,mid+1,r));
}//区间求最小值;
inline int point(const int id,const int sec) {                              //查询单点值
    if(tree[id].left == sec&&tree[id].right == sec) {
        return tree[id].sumn;
    }
    pushdown(id);
    int mid  = (tree[id].left+tree[id].right)>>1;
    if(sec <= mid) return point(tree[id].lid,sec);
    else return point(tree[id].rid,sec);
}//查询单点值;
int main() {                                                                //主函数;
    //to do;
    return 0;
}

  

标签:right,const,int,线段,tree,mid,离散,id,模板
来源: https://www.cnblogs.com/bikuhiku/p/Segment-Tree.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有