题目
题解思路
ST表 做法
定义一个方程 来表示从i开始长度为2的 j 次方的区间 中的最大值
转移方程如上 。
这样我们就可以O1的查询最大值了。
在 l 到 R的区间中 必然存在一个2的幂次 K 让 2的幂次 k+1大于区间长度 K小于长度
这样就能夹出最大值了。
线段树做法
改一下sum就成了
经典 只有查询的线段树
AC代码
ST表代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
long long f[200100][110] ;
long long a[200100] ;
int n;
int main ()
{
ios::sync_with_stdio(false);
cin>>n;
for (int i = 1 ; i <= n ; i++ )
cin>>a[i];
for (int j = 0 ; j < 18 ; j++ )
{
for (int i = 1 ; i + (1 << j ) - 1 <= n ; i++ )
{
if ( !j )
f[i][j] = a[i];
else
f[i][j] = max( f[i][j-1] , f[i+ (1<<j-1)][j-1] );
}
}
int m;
cin>>m;
while(m--)
{
int t1,t2;
cin>>t1>>t2;
int len = t2 - t1 + 1;
int k = log(len)/log(2); //换底
cout<< max(f[t1][k] , f[t2-(1<<k)+1][k] ) <<"\n";
}
return 0 ;
}
线段树代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
struct node
{
long long sum;
int l,r,lz;
};
const int N = 1001000 ;
long long a[N];
node tee[2*N];
int n;
void in(int i , int t1 , int t2)
{
tee[i].l = t1 , tee[i].r = t2;
if ( t1 == t2 )
{
tee[i].sum = a[t1];
tee[i].lz = 0 ;
return ;
}
int j = (t1+t2)/2;
in(i*2,t1,j);
in(i*2+1,j+1,t2);
tee[i].sum = max(tee[i*2].sum, tee[i*2+1].sum );
tee[i].lz = 0 ;
}
void pd(int i )
{
if ( tee[i].lz != 0 )
{
tee[i*2].lz += tee[i].lz;
tee[i*2+1].lz += tee[i].lz;
tee[i*2].sum += tee[i].lz*(tee[i*2].r - tee[i*2].l + 1 );
tee[i*2+1].sum += tee[i].lz*(tee[i*2+1].r - tee[i*2+1].l + 1 );
tee[i].lz = 0 ;
}
}
long long sea( int i ,int t1 , int t2 )
{
if ( tee[i].l >= t1 && tee[i].r <= t2 )
return tee[i].sum;
pd(i);
long long sum = -1000000;
if ( tee[i*2].r >= t1 )
sum = max(sea(i*2,t1,t2) , sum );
if ( tee[i*2+1].l <= t2 )
sum = max(sea(i*2+1,t1,t2), sum) ;
return sum;
}
void _add( int i , int t1 , int t2 , int vv )
{
if ( tee[i].l >= t1 && tee[i].r <= t2 )
{
tee[i].sum += vv*(tee[i].r - tee[i].l + 1);
tee[i].lz += vv ;
return;
}
pd(i);
if ( tee[i*2].r >= t1)
_add(i*2,t1,t2,vv);
if (tee[i*2+1].l <= t2)
_add(i*2+1,t1,t2,vv);
tee[i].sum = tee[i*2].sum + tee[i*2+1].sum;
}
int main ()
{
ios::sync_with_stdio(false);
cin>>n;
for (int i = 1 ; i <= n ; i++ )
cin>>a[i];
in(1,1,n);
int m;
vector <long long > ans ;
cin>>m;
for (int i = 1 ; i <= m ; i++ )
{
int t1,t2;
cin>>t1>>t2;
ans.push_back( sea(1, t1,t2) );
}
for ( auto i : ans )
cout<<i<<"\n";
return 0 ;
}