• 线段树【递归版本】


    一个功能较为全面的线段树:

    包括区间更新,区间查询最值(大/小),区间求和

    有完整注释以及一道板子题

    HDU-1166

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int maxn=5*1e4+7;
      4 int seq[maxn];  // must use index from 1
      5 
      6 struct Node{
      7     int l,r,maxx,minn;
      8     long long sum,lazy;
      9     // lazy for delaying child updating
     10     void update(int x){
     11         // update node storage value
     12         lazy+=x;
     13         sum+=1LL*(l-r+1)*x; // transfrom int to long long
     14         maxx+=x;
     15         minn+=x;
     16     }
     17     void __str__(){
     18         printf("l:%d r:%d maxx:%d minn:%d sum:%lld lazy:%lld
    ", 
     19                 l,r,maxx,minn,sum,lazy);
     20     }
     21 }Tree[maxn<<2]; // need 4 times space 
     22 
     23 void push_up(int id){
     24     // collect child node information
     25     Tree[id].sum=Tree[id<<1].sum+Tree[id<<1|1].sum;
     26     Tree[id].maxx=max(Tree[id<<1].maxx,Tree[id<<1|1].maxx);
     27     Tree[id].minn=min(Tree[id<<1].minn,Tree[id<<1|1].minn);
     28 }
     29 
     30 void push_down(int id){
     31     // only push down lazy to child, not update itselef
     32     // change itself value by push_up operation
     33     // if node has lazy value , push down lazy to child
     34     long long lazyval=Tree[id].lazy;
     35     if(lazyval){
     36         // cleaer lazy
     37         Tree[id].lazy=0; 
     38         // update child node, itself not change
     39         Tree[id<<1].update(lazyval);
     40         Tree[id<<1|1].update(lazyval);
     41     }
     42 }
     43 
     44 void build(int id,int l,int r){
     45     Tree[id].l=l;Tree[id].r=r;Tree[id].lazy=0;
     46     if(l==r){
     47         // leaf node
     48         Tree[id].sum=Tree[id].maxx=Tree[id].minn=seq[l];
     49     }else{
     50         // minddle node 
     51         int mid=l+((r-l)>>1);
     52         build(id<<1,l,mid);
     53         build(id<<1|1,mid+1,r);
     54         // update parent value
     55         push_up(id);
     56     }
     57 }
     58 
     59 void update(int id, int ql,int qr, int val){
     60     int L=Tree[id].l, R=Tree[id].r;
     61     if(ql<=L && R<=qr){
     62         // if query range contains range of now node, only to update it, 
     63         // don't update child, even to update leaf node.
     64         // only in this way to promise update operation by O(logn) 
     65         Tree[id].update(val);
     66     }else{
     67         push_down(id);
     68         int mid=L+((R-L)>>1);
     69         if(ql<=mid) update(id<<1,ql,qr,val);
     70         if(mid<qr) update(id<<1|1,ql,qr,val);
     71         push_up(id);
     72     }
     73 }
     74 
     75 long long querySum(int id,int ql,int qr){
     76     int L=Tree[id].l, R=Tree[id].r;
     77     if(ql<=L && R<=qr){
     78         // query range contains now node range, it dedicate that we can get result on the node
     79         return Tree[id].sum;
     80     }else{
     81         push_down(id);
     82         long long ans=0;
     83         int mid=L+((R-L)>>1);
     84         if(ql<=mid) ans+=querySum(id<<1,ql,qr);
     85         if(mid<qr) ans+=querySum(id<<1|1,ql,qr);
     86         push_up(id);
     87         return ans;
     88     }
     89 }
     90 
     91 int queryMax(int id, int ql, int qr){
     92     int L=Tree[id].l, R=Tree[id].r;
     93     if(ql<=L && R<=qr){
     94         return Tree[id].maxx;
     95     }else{
     96         push_down(id);
     97         int ans=-INF;
     98         int mid=L+((R-L)>>1);
     99         if(ql<=mid) ans=max(ans,queryMax(id<<1,ql,qr));
    100         if(mid<qr) ans=max(ans,queryMax(id<<1|1,ql,qr));
    101         push_up(id);
    102         return ans;
    103     }
    104 }
    105 
    106 int queryMin(int id, int ql, int qr){
    107     int L=Tree[id].l, R=Tree[id].r;
    108     if(ql<=L && R<=qr){
    109         return Tree[id].minn;
    110     }else{
    111         push_down(id);
    112         int ans=INF;
    113         int mid=L+((R-L)>>1);
    114         if(ql<=mid) ans=min(ans,queryMin(id<<1,ql,qr));
    115         if(mid<qr) ans=min(ans,queryMin(id<<1|1,ql,qr));
    116         push_up(id);
    117         return ans;
    118     }
    119 }
    120 
    121 int seqGet(int idx){
    122     // get value in seq by index
    123     return queryMax(1,idx,idx);
    124 }
    125 
    126 int n;
    127 int main(int argc, char const *argv[])
    128 {
    129     // https://vjudge.net/problem/HDU-1166
    130     int T,kase=1;
    131     char flag[10];
    132     scanf("%d",&T);
    133     while(T--){
    134         scanf("%d",&n);
    135         for(int i=1;i<=n;i++)
    136             scanf("%d",&seq[i]);
    137         build(1,1,n);
    138         // print_tree();
    139         printf("Case %d:
    ",kase++);
    140         int i,j;
    141         while(scanf("%s",flag) && flag[0]!='E'){
    142             scanf("%d %d",&i,&j);
    143             if(flag[0]=='A') update(1,i,i,j);
    144             else if(flag[0]=='S') update(1,i,i,-j);
    145             else printf("%lld
    ",querySum(1,i,j));
    146         }
    147     }
    148     return 0;
    149 }
  • 相关阅读:
    redis 订阅者与发布者(命令行)
    CentOS 6 使用 tptables 打开关闭防火墙与端口
    CentOS 7 使用 firewalld 打开关闭防火墙与端口
    Python面向对象编程-OOP
    python命名规则 PEP8编码规则(约定俗成)
    python 装饰器 概念
    python常用模块 os,datetime,time,MySQLdb,hashlib
    python xml.etree.ElementTree 处理xml 文件 变量 流 xml概念
    Pycharm小技巧
    python概要笔记2
  • 原文地址:https://www.cnblogs.com/TianyuSu/p/10859937.html
Copyright © 2020-2023  润新知