• 线段树的基本操作


    点更新:

     1 #include <fstream>                 //点更新
     2 #include <iostream>
     3 #include <cstdio>
     4 
     5 using namespace std;
     6 
     7 const int N=10000;
     8 int n,m,a[N];
     9 struct node
    10 {
    11     int left,right;
    12     int max_,sum_;
    13 }tree[4*N];
    14 
    15 void build(int id,int l,int r);//建一棵线段树
    16 int query_sum(int id,int l,int r);//查询区间和
    17 int query_max(int id,int l,int r);//查询区间最大值
    18 void update(int id,int pos,int val);//更新位置pos的值增加val
    19 
    20 int main()
    21 {
    22     //freopen("D:\input.in","r",stdin);
    23     //freopen("D:\output.out","w",stdout);
    24     int bo,t1,t2;
    25     scanf("%d%d",&n,&m);
    26     for(int i=1;i<=n;i++)
    27         scanf("%d",&a[i]);
    28     build(1,1,n);
    29     for(int i=1;i<=m;i++)
    30     {
    31         scanf("%d%d%d",&bo,&t1,&t2);
    32         if(bo)//更新(这里指增加)
    33             update(1,t1,t2);
    34         else
    35             printf("%d
    ",query_sum(1,t1,t2));
    36     }
    37     return 0;
    38 }
    39 void build(int id,int l,int r)
    40 {
    41     tree[id].left=l;
    42     tree[id].right=r;
    43     if(l==r)
    44     {
    45         tree[id].sum_=a[l];
    46         tree[id].max_=a[l];
    47     }
    48     else
    49     {
    50         int mid=(l+r)/2;
    51         build(2*id,l,mid);
    52         build(2*id+1,mid+1,r);
    53         tree[id].sum_=tree[2*id].sum_+tree[2*id+1].sum_;
    54         tree[id].max_=max(tree[2*id].max_,tree[2*id+1].max_);
    55     }
    56 }
    57 int query_sum(int id,int l,int r)
    58 {
    59     if(tree[id].left==l&&tree[id].right==r)
    60         return tree[id].sum_;
    61     else
    62     {
    63         int mid=(tree[id].left+tree[id].right)/2;
    64         if(r<=mid)  return query_sum(2*id,l,r);
    65         else if(l>mid)  return query_sum(2*id+1,l,r);
    66         else
    67             return query_sum(2*id,l,mid)+query_sum(2*id+1,mid+1,r);
    68     }
    69 }
    70 int query_max(int id,int l,int r)
    71 {
    72     if(tree[id].left==l&&tree[id].right==r)
    73         return tree[id].max_;
    74     else
    75     {
    76         int mid=(tree[id].left+tree[id].right)/2;
    77         if(r<=mid)  return query_max(2*id,l,r);
    78         else if(l>mid)  return query_max(2*id+1,l,r);
    79         else
    80             return max(query_max(2*id,l,mid),query_max(2*id+1,mid+1,r));
    81     }
    82 }
    83 void update(int id,int pos,int val)
    84 {
    85     if(tree[id].left==tree[id].right)
    86     {
    87         tree[id].sum_+=val;//假如修改而不是增加,就把+=改为=。
    88         tree[id].max_+=val;
    89     }
    90     else
    91     {
    92         int mid=(tree[id].left+tree[id].right)/2;
    93         if(pos<=mid)    update(2*id,pos,val);
    94         else update(2*id+1,pos,val);
    95         tree[id].sum_=tree[2*id].sum_+tree[2*id+1].sum_;
    96         tree[id].max_=max(tree[2*id].max_,tree[2*id+1].max_);
    97     }
    98 }
    View Code

    区间更新:

      1 #include <fstream>
      2 #include <iostream>
      3 #include <cstdio>
      4 
      5 using namespace std;
      6 
      7 const int N=100005;
      8 int n,m,a[N];
      9 struct node
     10 {
     11     int left,right;
     12     long long lazy,sum_;
     13 }tree[4*N];
     14 
     15 void build(int id,int l,int r);//建一棵线段树
     16 long long query_sum(int id,int l,int r);//查询区间和
     17 void update(int id,int p1,int p2,int val);//更新区间[p1,p2]的值增加val
     18 
     19 int main()
     20 {
     21     //freopen("D:\input.in","r",stdin);
     22     //freopen("D:\output.out","w",stdout);
     23     int bo,t1,t2,t3;
     24     scanf("%d%d",&n,&m);
     25     for(int i=1;i<=n;i++)
     26         scanf("%d",&a[i]);
     27     build(1,1,n);
     28     for(int i=1;i<=m;i++)
     29     {
     30         scanf("%d%d%d",&bo,&t1,&t2);
     31         if(bo)//更新(这里指增加)
     32         {
     33             scanf("%d",&t3);
     34             update(1,t1,t2,t3);
     35         }
     36         else
     37             printf("%lld
    ",query_sum(1,t1,t2));
     38     }
     39     return 0;
     40 }
     41 void build(int id,int l,int r)
     42 {
     43     tree[id].left=l;
     44     tree[id].right=r;
     45     tree[id].lazy=0;
     46     if(l==r)
     47     {
     48         tree[id].sum_=a[l];
     49     }
     50     else
     51     {
     52         int mid=(l+r)/2;
     53         build(2*id,l,mid);
     54         build(2*id+1,mid+1,r);
     55         tree[id].sum_=tree[2*id].sum_+tree[2*id+1].sum_;
     56     }
     57 }
     58 long long query_sum(int id,int l,int r)
     59 {
     60     if(tree[id].left==l&&tree[id].right==r)
     61         return tree[id].sum_;
     62     else
     63     {
     64         int mid=(tree[id].left+tree[id].right)/2;
     65         if(tree[id].lazy)
     66         {
     67             update(2*id,tree[id].left,mid,tree[id].lazy);
     68             update(2*id+1,mid+1,tree[id].right,tree[id].lazy);
     69             tree[id].lazy=0;
     70         }
     71         if(r<=mid)  return query_sum(2*id,l,r);
     72         else if(l>mid)  return query_sum(2*id+1,l,r);
     73         else
     74             return query_sum(2*id,l,mid)+query_sum(2*id+1,mid+1,r);
     75     }
     76 }
     77 void update(int id,int p1,int p2,int val)
     78 {
     79     if(tree[id].left==p1&&tree[id].right==p2)
     80     {
     81         tree[id].lazy+=val;
     82         tree[id].sum_+=val*(p2-p1+1);
     83     }
     84     else
     85     {
     86         int mid=(tree[id].left+tree[id].right)/2;
     87         if(tree[id].lazy)
     88         {
     89             update(2*id,tree[id].left,mid,tree[id].lazy);
     90             update(2*id+1,mid+1,tree[id].right,tree[id].lazy);
     91             tree[id].lazy=0;
     92         }
     93         if(p2<=mid)
     94             update(2*id,p1,p2,val);
     95         else if(p1>mid)
     96             update(2*id+1,p1,p2,val);
     97         else
     98         {
     99             update(2*id,p1,mid,val);
    100             update(2*id+1,mid+1,p2,val);
    101         }
    102         tree[id].sum_=tree[2*id].sum_+tree[2*id+1].sum_;
    103     }
    104 }
    View Code

    需要注意的是:线段树空间应开为原数组长度的4倍。

    空间复杂度~O(N*4),每次更新和查询操作的复杂度都是O(logN)。

  • 相关阅读:
    Dubbo探索(七)
    Dubbo探索(六)
    Dubbo探索(五)
    Dubbo探索(四)
    Redis主节点内存占用过高
    修改RedHat 7.2 进程最大句柄数限制
    Linux 数据分析常用 shell命令
    流处理
    根域名服务器
    并发与并行(concurrency vs parallesim)
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4145304.html
Copyright © 2020-2023  润新知