Multiplication and ST algorithm

Doubled

It is easy to understand that it is multiplication, which is equivalent to multiplying by 2 each time, so multiplication can usually be associated with binary bit operations. The characteristic of the multiplication method is that the first , second, fourth, …, 2 k 1, 2, 4, …, 2^k need to be calculated in advance1242K springboards, this requires that the data is static and not dynamic. If the data changes, all springboards have to be recalculated, and the springboards are meaningless.
   The classic applications of the multiplication method are: matrix fast power, suffix array, ST algorithm, LCA (nearest common ancestor). This section introduces the relatively simple ST algorithm, and also gives a classic problem of applying multiplication.

ST algorithm

The ST algorithm mainly solves the static RMQ problem, that is, the maximum and minimum access interval without changing the value. The main idea is to find the best value in a large area, and merge the small areas into a large area. The result is the best value among the separated areas and then find the result. It's a bit convoluted, for example:

要求1-20,那么我们可以分解成 min(或max)(dp[1][16],dp[17][20]);
能分解成min(或max)(dp[1][16],dp[17][20]); 这样当然也就是可以分解成这样:
min(或max)(dp[1][16],dp[20-16+1][20]);
就是有重复的,因为我们要求的最值所以重复不会影响结果。
dp[i][j]表示i到j存的最小/大值。
为什么是16那?不可以是10,14,15吗?
当然可以只不过用16会更优化 因为16是2的倍数,那么我们就可以引入倍增了。
ST思想:
 (1)把整个数列分为很多小区间,并提前计算出每个小区间的最值;
 (2)对任意一个区间最值查询,找到覆盖它的两个小区间,用两个小区间的最值算出答案。

It’s nice to use the picture of Mr. Luo, of course Mr. Luo writes better.
First, we first construct the ST array, which is the maximum value stored in the interval. The interval length is the maximum value of 1. Earlier we said that the multiplication acts as a springboard, so we can start from 2 0 2^020 jump to2 1 2^121 (that is, 21 isdivided into two evenly, using the idea of ​​dynamic programming) This is the interval length of2 1 2^12The maximum value of 1 , so that we can jump to2 2 2^222

until you can't jump (1<<k)>n can't jump anymore, it's longer than the original array length.

Insert picture description here
So we can find the recursive expression:
dp[l][k]=max(dp[l][ k - 1],dp[ r - 1<<( k - 1) + 1][ k - 1 ]);
length is 1 <<(k − 1) 1<<(k-1)1<<(k1 ) The end point isrrr starting point isr - 1 <<(k -r1<<(k1)+1
l l l is the left endpoint,kkk is the number of binary digits, that is, the length (2 to the power of k). rrr is the right endpoint.

P2880 USACO07JANBalanced Lineup G

Explain another day

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+7;

ll n,m;
ll d[50010][100],p[50001][100];
ll a[maxn],b[100];

int main() {
    
    
    scanf("%lld%lld",&n,&m);
    for(int i=1; i<=n; i++)scanf("%lld",&a[i]),d[i][0]=p[i][0]=a[i];
    b[0]=1;
    ll flag=0;
    for(int i=1; i<64; i++) {
    
    
        b[i]=b[i-1]*2;
        if(b[i]>=n) {
    
    
            flag=i;
            break;
        }
    }

    for(int i=1; i<=flag; i++) {
    
    
        for(int j=1;j<=n-b[i]+1;j++){
    
    
            d[j][i]=min(d[j][i-1],d[j+b[i-1]][i-1]);
            p[j][i]=max(p[j][i-1],p[j+b[i-1]][i-1]);
        }
    }

    while(m--) {
    
    
        ll l,r;
        scanf("%lld%lld",&l,&r);
        ll len=r-l+1;
        ll k;
        for(int i=0;i<=flag;i++){
    
    
            if(b[i]<=len){
    
    
                k=i;
            }else break;
        }
        ll minn=min(d[l][k],d[r-b[k]+1][k]);
        ll maxx=max(p[l][k],p[r-b[k]+1][k]);
        printf("%lld\n",maxx-minn);
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45911397/article/details/111085611