博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

RMQ算法

其实我们求 dp[i][j] 的时候可以把它分成两部分,第一部分是从 i 到 i + 2 ^( j-1 ) - 1 ,第二部分从 i + 2 ^( j-1 ) 到i + 2^j -1 ,为什么可以这么分呢?其实我们都知道二进制数前一个数是后一个的两倍,那么可以把 i ~ i + 2^j -1 这个区间 通过2^(j-1) 分成相等的两部分, 那么转移方程很容易就写出来了。(dp[i][0]就表示第i个数字本身)

 

dp[i][j] = min(dp [i][j - 1], dp [i + (1 << j - 1)][j - 1])

 1 void rmq_init()
 2 {
 3     for(int i=1;i<=N;i++)
 4         dp[i][0]=arr[i];//初始化
 5     for(int j=1;(1<<j)<=N;j++)
 6         for(int i=1;i+(1<<j)-1<=N;i++)
 7             dp[i][j]=min(dp[i][j-1],dp[i+(1<<j-1)][j-1]);
 8 }
 9 
10 int rmq(int l,int r)
11 {
12     int k=log2(r-l+1);
13     return min(dp[l][k],dp[r-(1<<k)+1][k]);
14 }
15  
16

 

posted @ 2019-04-26 10:07  GUET_uzi  阅读(123)  评论(0编辑  收藏  举报

- 创建于 2018年9月1日

这是一位ACM爱好者&数学爱好者的个人站,内容主要是算法&数据结构&数学研究的技术文章,大部分来自学习,部分来源于网络,希望对大家有所帮助。