ST表(跳跃表)

ST表(跳跃表)


解决静态区间最大值问题, O ( N l o g N ) O(NlogN) O(NlogN)预处理后, O ( 1 ) O(1) O(1)给出数列 A A A中下标在 l ∼ r l \sim r lr之间的数的最大值是多少

F [ i , j ] 表示数列 A 下标中在 A [ i , i + 2 j − 1 ] 区间的最大长度, i ∼ i + 2 j − 1 共 2 j 个数字 递推边界 F [ i , 0 ] = A [ i ] , 根据公式 F [ i ] [ j ] = m a x ( F [ i ] [ j − 1 ] , f [ i + 2 j − 1 ) ] [ j − 1 ] ) 询问时找出小于区间长度下最大的 K 次幂,因为 F [ l ] [ k ] , F [ r − 2 k + 1 ] [ k ] 一定可以覆盖 [ l , r ] O ( 1 ) 询问即可 F[i,j]表示数列A下标中在A[i,i+2^j-1]区间的最大长度,i \sim i+2^j-1 共2^j个数字\\递推边界F[i,0]=A[i],根据公式F[i][j]=max(F[i][j-1],f[i+2^{j-1})][j-1])\\ 询问时找出小于区间长度下最大的K次幂,因为F[l][k],F[r-2^k+1][k]一定可以覆盖[l,r]\\ O(1)询问即可 F[i,j]表示数列A下标中在A[i,i+2j1]区间的最大长度,ii+2j12j个数字递推边界F[i,0]=A[i],根据公式F[i][j]=max(F[i][j1],f[i+2j1)][j1])询问时找出小于区间长度下最大的K次幂,因为F[l][k],F[r2k+1][k]一定可以覆盖[l,r]O(1)询问即可

P3865 【模板】ST 表


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#define pb push_back 
#define mem(f, x) memset(f,x,sizeof(f)) 
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;

typedef long long ll;
const int N=1e6;

int w[N],n,m,M,f[N][20];

struct _ST
{
	/*
	O(NlogN)预处理区间最值,O(1)查询,数组下标从1开始 
	M=log(n)/log(2)+1;
	由于在class外部不允许访问私有成员,所以这将导致编译出错。
	*/
	void init(){
		memset(f,-1,sizeof f);
		for(int j=0;j<M;j++){
			for(int i=1;i+(1<<j)-1<=n;i++){
				if(!j)f[i][j]=w[i];
				else f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
			}
		}
	}
	int query(int l,int r){
		int k=log(r-l+1)/log(2);
		return max(f[l][k],f[r-(1<<k)+1][k]);
	}
}_ST;

int main()
{
	cin>>n>>m;
	
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	
	_ST.init();
	
	for(int i=1;i<=m;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",_ST.query(l,r));
	} 
	
	return 0;
}

P2251 质量检测


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#define pb push_back 
#define mem(f, x) memset(f,x,sizeof(f)) 
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;

typedef long long ll;
const int N=1e6;

int w[N],n,m,M,f[N][20];

struct _ST
{
	/*
	O(NlogN)预处理区间最值,O(1)查询,数组下标从1开始 
	M=log(n)/log(2)+1;
	由于在class外部不允许访问私有成员,所以这将导致编译出错。
	*/
	void init(){
		memset(f,0x3f,sizeof f);
		for(int j=0;j<M;j++){
			for(int i=1;i+(1<<j)-1<=n;i++){
				if(!j)f[i][j]=w[i];
				else f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
			}
		}
	}
	int query(int l,int r){
		int k=log(r-l+1)/log(2);
		return min(f[l][k],f[r-(1<<k)+1][k]);
	}
}_ST;

int main()
{
	cin>>n>>m;
	M=log(n)/log(2)+1;
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	
	_ST.init();
	
	for(int i=1;i+m-1<=n;i++){
		int l=i,r=l+m-1;
		printf("%d\n",_ST.query(l,r));
	} 
	return 0;
}

P1816 忠诚


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#define pb push_back 
#define mem(f, x) memset(f,x,sizeof(f)) 
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;

typedef long long ll;
const int N=1e5+10;

int w[N],n,m,M,f[N][20];

struct _ST
{
	/*
	O(NlogN)预处理区间最值,O(1)查询,数组下标从1开始 
	M=log(n)/log(2)+1;
	由于在class外部不允许访问私有成员,所以这将导致编译出错。
	*/
	void init(){
		memset(f,0x3f,sizeof f);
		for(int j=0;j<M;j++){
			for(int i=1;i+(1<<j)-1<=n;i++){
				if(!j)f[i][j]=w[i];
				else f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
			}
		}
	}
	int query(int l,int r){
		int k=log(r-l+1)/log(2);
		return min(f[l][k],f[r-(1<<k)+1][k]);
	}
}_ST;

int main()
{
	cin>>n>>m;
	M=log(n)/log(2)+1;
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	
	_ST.init();
	
	for(int i=1;i<=m;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d ",_ST.query(l,r));
	} 
	
	return 0;
}

P2880 [USACO07JAN]Balanced Lineup G


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <queue>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#define pb push_back 
#define mem(f, x) memset(f,x,sizeof(f)) 
#define fo(i,a,n) for(int i=(a);i<=(n);++i)
#define fo2(i,a,n) for(int i=(a);i<(n);++i)
#define debug(x) cout<<#x<<":"<<x<<endl;
using namespace std;

typedef long long ll;
const int N=1e5+10;

int w[N],n,m,M,f_max[N][16],f_min[N][16];

struct _ST
{
	/*
	O(NlogN)预处理区间最值,O(1)查询,数组下标从1开始 
	M=log(n)/log(2)+1;
	由于在class外部不允许访问私有成员,所以这将导致编译出错。
	*/
	void init(){
		memset(f_min,0x3f,sizeof f_min);
		memset(f_max,-1,sizeof f_max);
		for(int j=0;j<M;j++){
			for(int i=1;i+(1<<j)-1<=n;i++){
				if(!j)f_min[i][j]=w[i];
				else f_min[i][j]=min(f_min[i][j-1],f_min[i+(1<<(j-1))][j-1]);
			}
		}
		for(int j=0;j<M;j++){
			for(int i=1;i+(1<<j)-1<=n;i++){
				if(!j)f_max[i][j]=w[i];
				else f_max[i][j]=max(f_max[i][j-1],f_max[i+(1<<(j-1))][j-1]);
			}
		}
	}
	int query_min(int l,int r){
		int k=log(r-l+1)/log(2);
		return min(f_min[l][k],f_min[r-(1<<k)+1][k]);
	}
	int query_max(int l,int r){
		int k=log(r-l+1)/log(2);
		return max(f_max[l][k],f_max[r-(1<<k)+1][k]);
	}
}_ST;

int main()
{
	cin>>n>>m;
	M=log(n)/log(2)+1;
	for(int i=1;i<=n;i++)scanf("%d",&w[i]);
	
	_ST.init();
	
	for(int i=1;i<=m;i++){
		int l,r;
		scanf("%d%d",&l,&r);
		printf("%d\n",_ST.query_max(l,r)-_ST.query_min(l,r));
	} 
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值