模板_ST倍增

//
#include<bits/stdc++.h>
using namespace std;

const int N=1e6+7;      // 1<=n,q<=5e5
int in[N],dp[N][30];    // log2(1e6) == 19.931569 
int n,q;

// i: 以 i 为起始点的数组区间 
// j: 2^j 数组区间长度
// int cnt=(int)log2(n);
// 1+2^j<=n+1 == 2^j<=n 消去干扰源 区间可以移动但是不能超出范围

void init()
{
    int i,j,cnt=(int)log2(n);
    memset( dp,0,sizeof( dp ) );
    for( i=1;i<=n;i++ ) dp[i][0]=in[i];

    for( j=1;j<=cnt;j++ )
        for( i=1;i+(1<<j)<=n+1;i++ )
            dp[i][j]=max( dp[i][j-1],dp[ i+(1<<(j-1)) ][j-1] );
                        // 上一区间对半分
}

// int len=(int)log2( y-x+1 );
// y-(1<<len)+1 : y为区间终点 +1 复位至右起点

int f( int x,int y )
{
    int len=(int)log2( y-x+1 );
    return max( dp[x][len],dp[ y-(1<<len)+1 ][len] );
}

int main()
{
    int x,y,i;
    while( cin>>n>>q )
    {
        for( i=1;i<=n;i++ ) cin>>in[i];
        init();
        while( q-- )
        {
            cin>>x>>y; cout<<f( x,y )<<endl;
        }
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_63173957/article/details/125124928