zoukankan      html  css  js  c++  java
  • 树状数组求区间最大值(树状数组)(复习)

    如题。

    当遇到单点更新时,树状数组往往比线段树更实用。

    算法:

    设原数序列为a[i],最大值为h[i](树状数组)。

    1。单点更新:

    直接更新a[i],然后再更新h[i]。若h[i]的值有可能改变的,则表示区间一定包含i结点。那么就两层lowbit更新所有可能的h。

    单点更新时间复杂度O(logn*logn)

     1 void update(int x)
     2 {
     3     while(x<=n)
     4     {
     5         h[x]=a[x];
     6         for(int i=1;i<lowbit(x);i<<=1)
     7         h[x]=max(h[x],h[x-i]);
     8         x+=lowbit(x);
     9     }
    10     return ;
    11 }

    2。区间查询最大值:

    设要查询的区间为[L,R],那么就从h[R]开始找,要找[L,R]内的所有区间。所以依然是两层lowbit,然后R向前跳直到跳到L前面。

    区间查询最大值时间复杂度O(logn*logn)

     1 void findans(int begin,int end)
     2 {
     3     int ans=0;
     4     while(end>=begin)
     5     {
     6         ans=max(ans,h[end]);
     7         end--;
     8         for(;end-lowbit(end)>=begin;end-=lowbit(end))
     9         ans=max(ans,h[end]);
    10     }
    11     
    12     printf("%d
    ",ans);
    13     return ;
    14 }

    相关试题:hdu1754(单点修改,区间求最大值)

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cmath>
     5 using namespace std;
     6 const int maxn=300005;
     7 int h[maxn],a[maxn];
     8 int n,m;
     9 int lowbit(int x)
    10 {
    11     return x&(-x);
    12 }
    13 void update(int x)
    14 {
    15     while(x<=n)
    16     {
    17         h[x]=a[x];
    18         for(int i=1;i<lowbit(x);i<<=1)
    19         h[x]=max(h[x],h[x-i]);
    20         x+=lowbit(x);
    21     }
    22     return ;
    23 }
    24 void findans(int begin,int end)
    25 {
    26     int ans=0;
    27     while(end>=begin)
    28     {
    29         ans=max(ans,a[end]);
    30         end--;
    31         for(;end-lowbit(end)>=begin;end-=lowbit(end))
    32         ans=max(ans,h[end]);
    33     }
    34     
    35     printf("%d
    ",ans);
    36     return ;
    37 }
    38 int main()
    39 {
    40     //freopen("in.txt","r",stdin);
    41     //freopen("out.txt","w",stdout);
    42     while(scanf("%d%d",&n,&m)==2)
    43     {
    44         memset(h,0,sizeof(h));
    45         for(int i=1;i<=n;i++)
    46         {
    47             scanf("%d",&a[i]);
    48             update(i);
    49         }
    50         for(int i=1;i<=m;i++)
    51         {
    52             char c=getchar();
    53             while(c!='Q'&&c!='U')c=getchar();
    54             if(c=='U')//update
    55             {
    56                 int y,z;
    57                 scanf("%d%d",&y,&z);
    58                 a[y]=z;
    59                 update(y);
    60                 continue;    
    61             }
    62             if(c=='Q')//findans
    63             {
    64                 int y,z;
    65                 scanf("%d%d",&y,&z);
    66                 findans(y,z);
    67                 continue;
    68             }
    69         }
    70     }
    71     
    72     return 0;
    73 } 
  • 相关阅读:
    抽象类abstract
    final关键字特点
    继承ExtendsFour
    继承(继承中构造方法的关系)
    继承ExtendsTwo-super&this
    继承ExtendsOne
    静态
    构造方法与setXxx方法
    15.8
    15.7
  • 原文地址:https://www.cnblogs.com/937337156Zhang/p/6072330.html
Copyright © 2011-2022 走看看