Sparse Table (sparse table): referred ST
ST algorithm is based on dynamic programming algorithm, so it is essentially dynamic programming.
Its time complexity is: O (nlogn) -O (q ).
It is no longer appropriate interval for the data to make changes in the value of most inquiries.
Assuming now that there is a set of data, the minimum requirement [l, r] in the.
First, we know that:
for the interval [l, r]: its interval lengthlen = r-l+1
;
below the basic idea of ST:
it is based on dynamic programming, the best condition is: dp[i][j]
dp[i][j]
indicates the length of interval from start i ^ 2 j one section (i.e., the [i,(2^j)-1]
) the most value
(r - l + 1 = 2^j, l = i, ----> r = i+(2^j)+1)
For the interval [l, r], it can be divided into two sections, i.e., two uniform interval is divided into two:
[L, R & lt] ----> [L, R & lt '] + [L', R & lt], Therefore, the interval lengths of the two sections is len / 2,
if dp [i] [j] represents [l, r] the minimum of the interval,
then for dp[i][j] = min(dp[i][j-1],dp[i+2^(j-1)][j-1])
, that is the state transition equation .
It is understood that:
the interval length is halved: (2^j)/2 = 2^(j-1)
, the second two-dimensional sub-sections. 1 to J
DP [I ^ 2 + (. 1-J)] [-J. 1]):
r - l' + 1 = 2^(j-1),r = i + 2^j -1 ---->
l' = i+2^j -1+1-2^(j-1) -------> l' = i + 2^(j-1)
boundary:
dp[i][0] = a[i] (i = 1...n)
Write code:
for(int i = 1; i <= n; i++)
{
cin>>dp[i][0];
}
for(int j = 1; 1<<j <= n; j++)
{
for(int i = 1; i+(1<<j)-1<=n; i++)
{
dp[i][j] = min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
For i, an interval [l, r],
dp[i][j],l = i,r-i +1 = 2^j-----> r = i + (1<<j)-1,r <= n,
所以:i+(1<<j)-1 <= n
Interval Query:
[l, r] query minimum,
so as to satisfy k 2 ^k <= r-l+1
is the largest integer ,
then for the interval [l, r] is in the interval beginning and a length l 2 ^ k, and r and ending interval length of 2 ^ k
two cover sections
k = log2(r-l+1)
Then
ans = min(dp[l][1<<k],dp[r-(1<<k)+1][k])
l 'r is represented by:
r - l' + 1 = 1 << k ---> l' = r - (1<<k) + 1
Interval query code can be written as:
int rmq(int L, int R)
{
//int k = 0;
//while(1<<(k+1) <= R-L+1) k++;
int k = log2(r-l+1);
return min(dp[l][1<<k],dp[r-(1<<k)+1][k]);
}
Title:
https://www.luogu.org/problemnew/show/P1816
Code:
(pre-k)
#include <iostream>
#define MAXM 100005
#define N 30
#define LL long long
using namespace std;
LL dp[MAXM][N];
LL lg[MAXM];//k = lg[r-l+1]
int main()
{
int m,n;
cin>>m>>n;
lg[0] = -1;
for(int i = 1; i <= m; i++)
{
cin>>dp[i][0];
lg[i] = lg[i>>1] + 1;
}
for(int j = 1; 1<<j <= m; j++)
{
for(int i = 1; i+(1<<j)-1<=m; i++)
{
dp[i][j] = min(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
}
}
int flag = 1;
while(n--)
{
int l,r;
cin>>l>>r;
int k = lg[r-l+1];
if(flag)
{
cout<<min(dp[l][k],dp[r-(1<<k)+1][k]);
flag = 0;
}
else
cout<<" "<<min(dp[l][k],dp[r-(1<<k)+1][k]);
}
cout<<endl;
return 0;
}