ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ST表解决RMQ问题

2022-01-25 22:32:11  阅读:144  来源: 互联网

标签:RMQ int scanf ST Fmax init 解决 include


RMQ(区间最值查询),可以用线段树和ST表解决

  • 线段树 预处理 O (nlogn) 查询 O (logn) 支持在线修改

  • ST表 预处理 O (nlogn) 查询O(1) 不支持在线修改

1.区间最值差—可用线段树,但ST更短

在这里插入图片描述
在这里插入图片描述

#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
const int N = 50010;
int a[N];
int n,m;
int Fmax[N][20];
int Fmin[N][20];
void init()
{
	for(int i=1;i<N;i++)Fmax[i][0]=Fmin[i][0]=a[i];
	int k=log2(n);
	for(int j=1;j<=k;j++)
		for(int i=1;i<=n-(1<<j)+1;i++)
		{
			Fmax[i][j]=max(Fmax[i][j-1],Fmax[i+(1<<j-1)][j-1]);
			Fmin[i][j]=min(Fmin[i][j-1],Fmin[i+(1<<j-1)][j-1]);
		}
			
}
int RMQ(int l,int r)
{
	int k=log2(r-l+1);
	int m1=max(Fmax[l][k],Fmax[r-(1<<k)+1][k]);
	int m2=min(Fmin[l][k],Fmin[r-(1<<k)+1][k]);
	return m1-m2;
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)scanf("%d",a+i);
	init();
	while(m--)
	{
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",RMQ(l,r));
	}
}

2.最频繁值在这里插入图片描述

在这里插入图片描述

#include <iostream>
#include <cmath>
#include <stdio.h>
using namespace std;
const int N = 100010;
int a[N],cnt[N]={0};
int n,m;
int f[N][20];
int lg2[N];
void init_log()
{
    lg2[0]=-1;
    for(int i=1;i<N;i++)lg2[i]=lg2[i>>1]+1;
}
void init_ST()
{
    for(int i=1;i<=n;i++)f[i][0]=cnt[i];
    for(int j=1;j<=lg2[n];j++)
        for(int i=1;i+(1<<j)-1<N;i++)
            f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);
}
int RMQ(int l,int r)
{
    int k=lg2[r-l+1];
    return max(f[l][k],f[r-(1<<k)+1][k]);
}
void solve()
{
    scanf("%d",&m);
    
    for(int i=1;i<=n;i++)
    {   
        scanf("%d",a+i);
        if(a[i]!=a[i-1])cnt[i]=1;
        else cnt[i]=cnt[i-1]+1;
    }
    init_ST();
    while (m -- ){
        int l,r;
        scanf("%d%d",&l,&r);
        int t=l;
        while(a[t]==a[l-1]&&t<=r)t++;
        if(t>r)printf("%d\n",t-l);
        else printf("%d\n",max(t-l,RMQ(t,r)));
    }
}
signed main()
{
    init_log();
    while(cin>>n,n)solve();
}

3.炸鸡块君与FIFA22

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include <iostream>
using namespace std;
const int N = 200010;
int f[3][N][20];
char s[N];
signed main()
{
	int n,m;
    cin>>n>>m;
    cin>> s+1 ;
    for(int j=0;j<3;j++)
        for(int i=1;i<=n;i++)
        {
            if(s[i]=='W')f[j][i][0]=1;
            else if(s[i]=='L')
            {
                if(!j)f[j][i][0]=0;
                else f[j][i][0]=-1;
            }
            else f[j][i][0]=0;
        }
    //类似于区间DP   初始化ST表
    for(int j=1;j<=20;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            for(int k=0;k<3;k++)
                f[k][i][j]=f[k][i][j-1]+f[(k+f[k][i][j-1])%3][i+(1<<j-1)][j-1];
    // query ST
    int l,r,x;
    while(m--)
    {
        scanf("%d%d%d",&l,&r,&x);
        for(int j=20;j>=0;j--)
        {
            if(l+(1<<j)-1>r)continue;
            x+=f[x%3][l][j];
            l+=(1<<j);
        }
        printf("%d\n",x);
    }
}

标签:RMQ,int,scanf,ST,Fmax,init,解决,include
来源: https://blog.csdn.net/qq_51282224/article/details/122681913

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有