• 模板


      自己总结的模板,需要根据具体情况添加或者修改一部分操作。

      1 #include <cstdio>
      2 #include <cstring>
      3 #define max(x,y) (x > y ? x : y)       //判断区间最值的操作符
      4 #define INF (1<<30)
      5 #define MAX 10000                      //总区间的容量
      6 using namespace std;
      7 
      8 int s[MAX];                            //原始数据
      9 
     10 typedef struct{
     11     int l,r;
     12     int info;
     13 }node;                                 //线段树的结点
     14 
     15 node t[MAX<<2];                        //线段树
     16 
     17 /**
     18  * 构造线段树
     19  * l,r分别为当前子树的根节点可以覆盖的范围(闭区间)
     20  * p代表当前子树的根节点在数组中的下标
     21  */
     22 void build(int l,int r,int p){
     23     /**每一次访问新的节点都是一棵子树的根节点**/
     24     /**所以每一次访问到新的根节点的时候都将覆盖的范围赋值给对应的变量**/
     25     t[p].l=l;
     26     t[p].r=r;
     27     if(l==r){//当前节点为叶子
     28        t[p].info==s[l];
     29        return ;
     30     }
     31     int mid=(l+r)/2;                             //或 mid=l+(r-l)/2
     32     build(l,mid,p*2);                            //构造左子树
     33     build(mid+1,r,p*2+1);                        //构造右子树
     34     t[p].info=max(t[p*2].info,t[p*2+1].info);    //跟新当前这个根节点的覆盖的范围的最值
     35 }
     36 
     37 /**
     38  * 查询区间最值
     39  * l,r为总的查询区间范围
     40  * p为当前子树的根节点在数组中的下标
     41  */
     42 int query(int l,int r,int p){
     43     int mid=(t[p].l+t[p].r)/2;      //或 mid=t[p].l+(t[p].r-t[p].l)/2
     44     int e;
     45     int ans=-INF;                   //保存在当前这一棵子树里面包含查询区间的那一部分区间的最值
     46     if(l<=t[p].l && r<=t[p].r){
     47         //如果查询范围是在当前子树的覆盖范围里面
     48         return t[p].info;
     49     }
     50     if(l<=mid){
     51         //当前子树的左子树中包含查询范围的一部分
     52         e=query(l,r,p*2);
     53         ans=max(ans,e);
     54     }
     55     if(r>mid){
     56         //当前子树的右子树中包含查询范围的一部分
     57         e=query(l,r,p*2+1);
     58         ans=max(ans,e);
     59     }
     60     return ans;
     61 }
     62 
     63 /**
     64  * 将一个区间每一个元素的值更新为同一个新值,同时更新区间最值
     65  * l,r为需要更新每一个元素的值得区间
     66  * p为当前子树的根节点在数组中的下标
     67  * e为需要更新的新值
     68  */
     69 void update(int l,int r,int p,int e){
     70     int mid=(t[p].l+t[p].r)/2;        //或 mid=t[p].l+(t[p].r-t[p].l)/2
     71     if(t[p].l==t[p].r){
     72         //当前节点是树叶,修改其信息
     73         t[p].info=e;
     74     }
     75     else{
     76         if(l<=mid){
     77            //当前节点的左子树包含需要更新的区间的一部分
     78            update(l,r,p*2,e);
     79         }
     80         else{
     81            //当前节点的右子树包含需要更新的区间的一部分
     82            update(l,r,p*2+1,e);
     83         }
     84         //更新当前区间的最值
     85         t[p].info=max(t[p*2].info,t[p*2+1].info);
     86     }
     87 }
     88 
     89 /**
     90  * 重置保存原始信息的数组和线段树
     91  */
     92 void reset(){
     93     memset(s,0,sizeof(s));
     94     memset(t,0,sizeof(t));
     95 }
     96 
     97 int main()
     98 {
     99     //reset();
    100     return 0;
    101 }
  • 相关阅读:
    排序算法之归并
    RequestAndResponse
    Jsp相关
    会话技术
    MVC设计思想
    FileRecv VNCViewer 使用方法
    Go语言string包详解
    Go语言字符串
    Go语言fmt包详解
    编写第一个Go程序
  • 原文地址:https://www.cnblogs.com/sineatos/p/3576453.html
Copyright © 2020-2023  润新知