首页 > 代码库 > 树状数组求区间最大值(树状数组)(复习)

树状数组求区间最大值(树状数组)(复习)

如题。

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

算法:

设原数序列为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\n",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\n",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)//update55             {56                 int y,z;57                 scanf("%d%d",&y,&z);58                 a[y]=z;59                 update(y);60                 continue;    61             }62             if(c==Q)//findans63             {64                 int y,z;65                 scanf("%d%d",&y,&z);66                 findans(y,z);67                 continue;68             }69         }70     }71     72     return 0;73 } 

 

树状数组求区间最大值(树状数组)(复习)