首页 > 其他 > 详细

[Luogu] 洛谷 P2880 题解【[USACO07JAN]平衡的阵容Balanced Lineup】

时间:2018-10-14 19:48:16      阅读:146      评论:0      收藏:0      [点我收藏+]

我又来发一篇题解啦

其实这一题只是一道板子题,但因为我对RMQ又有些不记得了

所以发篇题解加深印象

直入正题

核心思想是DP+倍增

不妨我们先来看一个1,2,3,4,……2^n的例子

它的最大值一定是1~2^(n-1)的max与2^(n-1)+1的max的max

这样我们每次算下去就可以很快地得出答案

那么问题来了,如果我们询问的区间不是长度为2^n的呢?

不妨假设它的长度为l,令s=floor(log(l))(以下的log底数为2)

则它的最大值一定是从头取2^s个的这一段区间的max与从尾取2^s个的这一段区间的max(两者会有重叠的部分,不过不影响)

如此,这一题就搞完啦QAQ

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[50001];
int logg[50001];
int f_min[50001][20],f_max[50001][20];
int main(){
    cin>>n>>m;
    for(int i=1;i<=n;i++)
      cin>>a[i];
    logg[0]=-1;
    for(int i=1;i<=n;i++)
      f_min[i][0]=a[i],f_max[i][0]=a[i],logg[i]=logg[i>>1]+1;
    for(int j=1;(1<<j)<=n;j++)
      for(int i=1;i+(1<<j)-1<=n;i++)//循环顺序一定不能变,要先算出长度为2^(j-1)才能算2^j的
      {
        f_min[i][j]=min(f_min[i][j-1],f_min[i+(1<<j-1)][j-1]);
        f_max[i][j]=max(f_max[i][j-1],f_max[i+(1<<j-1)][j-1]);
      }
    for(int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        int s=logg[y-x+1];
        cout<<max(f_max[x][s],f_max[y-(1<<s)+1][s])-min(f_min[x][s],f_min[y-(1<<s)+1][s])<<endl;
    }
}

[Luogu] 洛谷 P2880 题解【[USACO07JAN]平衡的阵容Balanced Lineup】

原文:https://www.cnblogs.com/wo-shi-zhen-de-cai/p/9787483.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!