sparse table

# Sparse table RMQ problem solving
to channel water problem

Article Directory

When milking every day, Farmer John’s N cows (1≤n≤50000) are always lined up. One
day, John decides to play an ultimate frisbee game with his cows. For the sake of simplicity, he will select a certain range of cows from the cow queue to play this game. However, all the cows are very interested in this game. Farmer John made a list of Q copies (1≤Q≤200000) and the height of each cow (1≤height≤1000000). For each list, he wants you to help him determine the height difference between the highest cow and the lowest cow in each list.

The
first line of Input is N(1≤N≤50000) and Q(1≤Q≤200000); from line 2 to line N+1, each line has a number, indicating the height of the i-th cow (1≤height≤ 1000000); From the N+2th row to the N+Q+1th row, each row has two integers A and B (1≤A≤B≤N), representing the range from the Ath cow to the Bth cow.

Output
from the first row to the Qth row, each row has an integer, which represents the height difference between the highest cow and the shortest cow from the Ath cow to the Bth cow.

Pretreatment:

Using the idea of ​​DP, f[i][j] represents the minimum value in the interval [i, i+2∧j-1 (that is, the minimum value of consecutive 2j numbers from the i-th number). Number sequence 3,2,4,5,6,8,1,2,9,7. f[1][0]=3, f[1][1]=2, f[1][2]=2, f[1][3]=1, f[2][0]=2, f[2][1]=2, f[2][2]=2…… f[i][j] can be composed of f[i][j-1] and f[i+2j-1][j -1] Derive: f[i][j-1] represents the minimum value of the interval [i, i+2j-1-1] f[i+2j-1][j-1] represents the interval [i+2^ j-1^, i+2[^j-1+2j-1-1]=[i+2j-1, i+2j-1] minimum value, so there is the DP equation: **f[i][ j]=min(f[i][j-1],f[i+2[^j-1^][j-1])**
   for(j=1;j<=floor(log2(n));j++)
    for(i=1;i<=(n-(1<<j)+1);i++)
    {
    
    
         Fmin[i][j] = min( Fmin[i][j-1] , Fmin[i+1<<(j-1)][j-1] );
         Fmax[i][j] = max( Fmax[i][j-1] , Fmax[i+1<<(j-1)][j-1] );
    }

Inquire:

上例中要求区间[2,8]的最小值,就要把它分成[2,5]和[5,8]两个区间,因为这两个区间的最小值可以直接由f[2][2]和f[5][2]得到。

Extending to the general case, the interval [a,b] is divided into two intervals of 2k length [a,a+2k-1] and interval [b-2k+1,b] (guarantee f[i][j ]correspond).
The minimum value of the interval [1,8]=f[1][3] k=3
The minimum value of the interval [2,8]=min(f[2][2],f[5][2]); k =2
k=floor(log2(b-a+1)) //that is, 2 k = b-a+1
interval [a,b] minimum value MinA_B=min(f[a][k],f[b -2∧k+1][k])


k=floor(log2(b-a+1));
RMinQ[a][b] = min( Fmin[a][k] , Fmin[b-(1<<k) +1][k]  );
RMaxQ[a][b] = max( Fmax[a][k] , Fmax[b-(1<<k) +1][k]  );
//注意要加一,而且位运算优先级很低

Sample code

#include<bits/stdc++.h>
using namespace std;
int shu[50009];
int f[50009][20];
int ff[50009][20];
int n,m;

void slove()
{
    
    
	memset(f,-1,sizeof(f));
	memset(ff,0xf,sizeof(ff));
	for(int i=1;i<=n;i++)
	{
    
    
		f[i][0]=shu[i];
		ff[i][0]=shu[i];
	}
	int k=floor(log2(n));
	for(int j=1;j<=k;j++)
	for(int i=1;i<=(n-(1<<j)+1);i++)
	{
    
    
		f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]);
		ff[i][j]=min(ff[i][j-1],ff[i+(1<<(j-1))][j-1]);
	}
	return ;
}
void query(int l,int r)
{
    
    
	int k=floor(log2(r-l+1));
	int ans=max(f[l][k],f[r-(1<<k)+1][k]);
	ans=ans-min(ff[l][k],ff[r-(1<<k)+1][k]);
	printf("%d\n",ans);
	return ;
}
int main()
{
    
    
	freopen("data.in","r",stdin);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
		scanf("%d",&shu[i]);
	slove();
	int l,r;
	while(m--)
	{
    
    
		scanf("%d%d",&l,&r);
		query(l,r);
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/m0_50089378/article/details/109322316