• 线段树--数据结构专题学习


    这两周是数据结构专题的学习,,被专题的题目虐得死去活来==

    线段树:简单的说就是把【1,n】的区间二分,【1,(1+n)/2】左子树,【(1+n)/2+1,n】右子树

        就这样一直分下去,直到都是【x,x】这样的区间。这样就构成了一颗树了^-^

              有这样一棵树,我们就可以在节点中储存区间的和啊,区间内的最大值啊,最小值等等。。这就是线段树的附加信息了,也是题目中的重点。。

        我们可以用一个数组(长度为k)储存原区间的初始值,然后根据这个建树,所以这个树的节点数最多为4*K;

        对于每个节点i,其左子树为i*2,右子树为i*2+1,父母节点为i/2。该区间的sum为左右子树区间和的和,最大最小值同理。。。

        线段树的建立,修改,查询都是用递归写的。

        所以在对单个数值时,必定会影响到其祖先节点,所以从上往下写。递归后修改节点信息。

        线段树的查询也是如此,从上向下查询。

        先贴模板

     1 #include <bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 #define MP make_pair
     6 #define PB push_back
     7 typedef long long LL;
     8 typedef pair<int,int> PII;
     9 const double eps=1e-8;
    10 const double pi=acos(-1.0);
    11 const int K=1e6+7;
    12 const int mod=1e9+7;
    13 
    14 
    15 struct node
    16 {
    17     int max,sum;
    18     int left,right;
    19 };
    20 struct node tree[4*K];
    21 int a[K];
    22 void build(int id,int l,int r)
    23 {
    24     tree[id].left=l,tree[id].right=r;
    25     if(l==r)
    26         tree[id].max=tree[id].sum=a[l];
    27     else
    28     {
    29         build(2*id,l,(l+r)/2),build(2*id+1,(l+r)/2+1,r);
    30         tree[id].max=max(tree[2*id].max,tree[2*id+1].max);
    31         tree[id].sum=tree[2*id].sum+tree[2*id+1].sum;
    32     }
    33 }
    34 int queryMax(int id,int l,int r)
    35 {
    36     if(l==tree[id].left && r==tree[id].right)
    37         return tree[id].max;
    38     int mid=(tree[id].left+tree[id].right)>>1;
    39     if(r<=mid)
    40         return queryMax(id<<1,l,r);
    41     else if(l>=mid+1)
    42         return queryMax((id<<1)+1,l,r);
    43     else
    44         return max(queryMax(id<<1,l,mid),queryMax((id<<1)+1,mid+1,r));
    45 }
    46 int querySum(int id,int l,int r)
    47 {
    48     if (tree[id].left==l&&tree[id].right==r)
    49         return tree[id].sum;
    50     int mid=(tree[id].left+tree[id].right)>>1;
    51     if (r<=mid)
    52         return querySum(id*2,l,r);
    53     else if (l>mid)
    54         return querySum(id*2+1,l,r);
    55     else
    56         return querySum(id*2,l,mid)+querySum(id*2+1,mid+1,r);
    57 }
    58 void update(int id,int pos,int v)
    59 {
    60     if(tree[id].left == tree[id].right)
    61         tree[id].sum=tree[id].max=v;
    62     else
    63     {
    64         int mid=(tree[id].left+tree[id].right)>>1;
    65         if (pos<=mid) update(id*2,pos,v);
    66         else update(id*2+1,pos,v);
    67         tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
    68         tree[id].max=max(tree[id*2].max,tree[id*2+1].max);
    69     }
    70 }
    71 int main(void)
    72 {
    73 
    74     return 0;
    75 }

        带区间修改的版本:

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <cstdio>
      4 #include <cmath>
      5 #include <cstring>
      6 #include <queue>
      7 #include <stack>
      8 #include <map>
      9 #include <vector>
     10 #include <cstdlib>
     11 #include <string>
     12 
     13 #define PI acos((double)-1)
     14 #define E exp(double(1))
     15 using namespace std;
     16 #define K 10000
     17 struct node
     18 {
     19     int maxt,sum,lazy;//sum代表节点信息,按题目更改
     20     int left,right;
     21 };
     22 struct node tree[4*K];
     23 int a[K];
     24 void build(int id,int l,int r)
     25 {
     26     tree[id].left=l;tree[id].right=r;tree[id].lazy=0;
     27     if(l==r)
     28     {
     29         tree[id].maxt=tree[id].sum=a[l];
     30     }
     31     else
     32     {
     33         build(2*id,l,(l+r)/2);
     34         build(2*id+1,(l+r)/2+1,r);
     35         tree[id].maxt=max(tree[2*id].maxt,tree[2*id+1].maxt);
     36         tree[id].sum=tree[2*id].sum+tree[2*id+1].sum;
     37     }
     38 }
     39 void pushdowm(int id)
     40 {
     41     if(tree[id].lazy)
     42     {
     43         tree[id*2].lazy=tree[id].lazy;
     44         tree[id*2+1].lazy=tree[id].lazy;
     45         tree[id*2].sum+=tree[id].lazy;
     46         tree[id*2+1].sum+=tree[id].lazy;
     47         tree[id].lazy=0;
     48     }
     49 }
     50 int queryMax(int id,int l,int r)
     51 {
     52     if(l==tree[id].left && r==tree[id].right)
     53         return tree[id].maxt;
     54     int mid=(tree[id].left+tree[id].right)>>1;
     55     int ret=0;
     56     pushdowm(id);
     57     if(r<=mid)
     58         ret=max(ret,queryMax(id<<1,l,r));
     59     else if(l>=mid+1)
     60         ret=max(ret,queryMax((id<<1)+1,l,r));
     61     else
     62     {
     63         int a,b;
     64         a=queryMax(id<<1,l,mid);
     65         b=queryMax((id<<1)+1,mid+1,r);
     66         return max(a,b);
     67     }
     68     return ret;
     69 }
     70 int update(int id,int pos,int v)
     71 {
     72     if(tree[id].left == tree[id].right)
     73     {
     74         tree[id].sum=tree[id].maxt=v;
     75     }
     76     else
     77     {
     78         int mid=(tree[id].left+tree[id].right)>>1;
     79         if (pos<=mid) update(id*2,pos,v);
     80             else update(id*2+1,pos,v);
     81         tree[id].sum=tree[id*2].sum+tree[id*2+1].sum;
     82         tree[id].maxt=max(tree[id*2].maxt,tree[id*2+1].maxt);
     83     }
     84     return 0;
     85 }
     86 void update_interal(int id,int l,int r,int v)
     87 {
     88     if(l==tree[id].left && r==tree[id].right)
     89     {
     90         tree[id].lazy+=v,tree[id].sum+=v;return;
     91     }
     92     pushdowm(id);
     93     int mid=(tree[id].left+tree[id].right)>>1;
     94     if(r<=mid)
     95         update_interal(id*2,l,r,v);
     96     else if(l>mid)
     97         update_interal(id*2+1,l,r,v);
     98     else
     99     {
    100         update_interal(id*2,l,mid,v);
    101         update_interal(id*2+1,mid+1,r,v);
    102         tree[id].sum+=tree[id*2].sum+tree[id*2+1].sum;
    103     }
    104 }
    105 int query(int id,int l,int r)
    106 {
    107         if (tree[id].left==l&&tree[id].right==r)
    108             return tree[id].sum;
    109         else
    110         {
    111             int mid=(tree[id].left+tree[id].right)>>1;
    112             pushdowm(id);
    113             if (r<=mid) return query(id*2,l,r);
    114             else if (l>mid) return query(id*2+1,l,r);
    115             else return query(id*2,l,mid)+query(id*2+1,mid+1,r);
    116         }
    117 }
    118 
    119 int main(void)
    120 {
    121     int n,l,r,v;
    122     cin>>n;
    123     for(int i=1;i<=n;i++)
    124         a[i]=i;
    125     build(1,1,n);
    126     printf("%d
    ",query(1,1,10));
    127     cin>>l>>r>>v;
    128     update_interal(1,l,r,v);
    129     printf("%d
    ",query(1,l,r));
    130     return 0;
    131 }
    View Code
  • 相关阅读:
    Pycharm(一)下载安装
    Django(一)创建和启动项目
    windows10自动登陆
    Tushare安装
    笑话
    python异常处理
    XPath与Xquery
    XML相关概念
    JDK、JRE、JVM三者间的关系
    CMS
  • 原文地址:https://www.cnblogs.com/weeping/p/5423382.html
Copyright © 2020-2023  润新知