RMQ 问题——ST表

简介: RMQ 问题——ST表

文章目录

RMQ问题

不带修改的区间最值,重叠的区间不会对区间的最大值产生影响

可以用 ST表(稀疏表)

(不带修改的区间问题可以用,一经修改就不可以用了)

例题模板:区间最值

 int dp[8][35];//dp[i][j]表示左端点为i,长度为2^j这样的长度的区间,也就是<==>ans[i][i+2^j-1]
 int query(int l, int r )
 {
  int j = (int)log2(r - l + 1);
   return max(dp[l][j], dp[r - (1 << j) + 1][j]);//区间最大值可以有重合覆盖上,右边长度还是j
 }
 int main()
 { 
   int arr[8] = { 9,3,1,7,5,6,0,8 };
   int n = 8;
//填充dp[i][j]
   for (int i = 0; i < n; i++)
   {
     dp[i][0] = arr[i];//ans[i][i+2^0-1]=arr[i]
   }
   for (int j = 1; j <= log2(n); j++)//j=0已经处理了,先要枚举j,而不是先枚举i,j的最大长度是log2(n);
   {
     for (int i = 0; i + (1 << j) - 1 < n; i++)// i + (1 << j) - 1是区间的右端点,要小于n,不要越界,
     {
       dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);//把一个长的区间,把他砍一半,,一半一半的求
       //j-1相当于区间长度取了一半,一半一半的求最值
       // dp[i][j]的值为,最值(dp[i][j-1]相当于[i][i+2^(j-1)-1]的区间,与[i+2^(j-1)][i+2^(j-1)+2^(j-1)-1]的最值
     }
   }
   int l, r;//左右断电
   while (cin >> l >> r)
   {
     cout << query(l, r) << endl;//query就是询问函数询问l,r的区间最大值
   }
   return 0;
 }

例题:区间最大公约数

int gcd(int a,int b)
{
return b?gcd(b,a%b):0;
}
int dp[8][35];//dp[i][j]表示左端点为i,长度为2^j这样的长度的区间,也就是<==>ans[i][i+2^j-1]
int query(int l, int r)
{
  int j = (int)log2(r - l + 1);
  return gcd(dp[l][j], dp[r - (1 << j) + 1][j]);//区间最大值可以有重合覆盖上,右边长度还是j
}
int main()
{
  int arr[8] = { 9,3,15,12,5,6,0,8 };
  int n = 8;
  //填充dp[i][j]
  for (int i = 0; i < n; i++)
  {
    dp[i][0] = arr[i];//ans[i][i+2^0-1]=arr[i]
  }
  for (int j = 1; j <= log2(n); j++)//j=0已经处理了,先要枚举j,而不是先枚举i,j的最大长度是log2(n);
  {
    for (int i = 0; i + (1 << j) - 1 < n; i++)// i + (1 << j) - 1是区间的右端点,要小于n,不要越界,
    {
      dp[i][j] = gcd(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);//把一个长的区间,把他砍一半,,一半一半的求
      //j-1相当于区间长度取了一半,一半一半的求最值
      // dp[i][j]的值为,最值(dp[i][j-1]相当于[i][i+2^(j-1)-1]的区间,与[i+2^(j-1)][i+2^(j-1)+2^(j-1)-1]的最值
    }
  }
  int l, r;//左右断电
  while (cin >> l >> r)
  {
    cout << query(l, r) << endl;//query就是询问函数询问l,r的区间最大值
  }
  return 0;
}

区间最大间距

#include<iiostream>
using namespace std;
int dpmax[30][35];
int dpmin[30][35];
//区间最值差
int querymax(int l, int r)
{
  int j =(int) log2(r - l + 1);
  return max(dpmax[l][j], dpmax[r - (1 >> j) + 1][j] );
}
int querymin(int l, int r)
{
  int j = (int)log2(r - l + 1);
  return min(dpmin[l][j], dpmin[r - (1 << j) + 1][j]);//区间最大值可以有重合覆盖上,右边长度还是j
}
int main()
{
  int n,m;
  cin >> n>>m;
  int arr[25]; 
  //预处理
  for(int i = 0; i < n; i++)
  {
    cin >> arr[i];
  dpmax[i][0] = arr[i];
  dpmin[i][0] = arr[i];
  }
  for (int j = 1; j <= log2(n); j++)
  {
    for (int i = 0; i + (1 << j) - 1 < n; i++)
    {
      dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]);
        dpmin[i][j]=min(dpmin[i][j - 1], dpmin[i + (1 << (j - 1))][j-1]);
    }
    }
  while (m--)
  {
    int l, r;
    cin >> l >> r;
    cout << querymax(l,r)-querymin(l,r) << endl;
  }
    return 0;
}
相关文章
|
2天前
|
数据采集 人工智能 安全
|
11天前
|
云安全 监控 安全
|
3天前
|
自然语言处理 API
万相 Wan2.6 全新升级发布!人人都能当导演的时代来了
通义万相2.6全新升级,支持文生图、图生视频、文生视频,打造电影级创作体验。智能分镜、角色扮演、音画同步,让创意一键成片,大众也能轻松制作高质量短视频。
1020 151
|
3天前
|
编解码 人工智能 机器人
通义万相2.6,模型使用指南
智能分镜 | 多镜头叙事 | 支持15秒视频生成 | 高品质声音生成 | 多人稳定对话
|
16天前
|
机器学习/深度学习 人工智能 自然语言处理
Z-Image:冲击体验上限的下一代图像生成模型
通义实验室推出全新文生图模型Z-Image,以6B参数实现“快、稳、轻、准”突破。Turbo版本仅需8步亚秒级生成,支持16GB显存设备,中英双语理解与文字渲染尤为出色,真实感和美学表现媲美国际顶尖模型,被誉为“最值得关注的开源生图模型之一”。
1716 9
|
8天前
|
人工智能 自然语言处理 API
一句话生成拓扑图!AI+Draw.io 封神开源组合,工具让你的效率爆炸
一句话生成拓扑图!next-ai-draw-io 结合 AI 与 Draw.io,通过自然语言秒出架构图,支持私有部署、免费大模型接口,彻底解放生产力,绘图效率直接爆炸。
659 152
|
10天前
|
人工智能 安全 前端开发
AgentScope Java v1.0 发布,让 Java 开发者轻松构建企业级 Agentic 应用
AgentScope 重磅发布 Java 版本,拥抱企业开发主流技术栈。
623 13