1. 程式人生 > 其它 >P3865 【模板】ST 表

P3865 【模板】ST 表

P3865 【模板】ST 表

題目簡述

對於給定的數列,要求以\(\theta(1)\)的時間複雜度計算出\([l_i,r_i]\)中最大值


思路

沒什麼可講的,但要注意,計算區間長度的對數要是 log2(r-l+1) 不加1的話大多數情況下沒問題,但是當 l=r 的時候會報錯
BTW,用scanf printf 不會超時,用cin cout 是會超時的qwq
具體思路可以參考這個部落格


程式碼

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int a[N],s[N][25];
int n,m;
void in(int &x){
  x=0;
  int f=1;
  char c=getchar();
  while(c>'9'||c<'0'){
    if(c=='-')f=-1;
    c=getchar();
  }
  while(c>='0'&&c<='9'){
    x=(x<<1)+(x<<3)+c-'0';
    c=getchar();
  }
  x*=f;
}
void pre_work(){
  for(int i=1;(1<<i)<=n&&i<25;i++){
    for(int j=1;j+(1<<i)-1<=n;j++){
      s[j][i]=max(s[j][i-1],s[j+(1<<(i-1))][i-1]);
    }
  }
}
void query(int l,int r){
  int k=log2(r-l+1);
  printf("%d\n",max(s[l][k],s[r-(1<<k)+1][k]));
}

int main(){
  in(n);in(m);
  for(int i=1;i<=n;i++)in(s[i][0]);
  pre_work();
  for(int i=1;i<=m;i++){
    int l,r;
    in(l);in(r);
    query(l,r);
  }
  return 0;
}