ST表-求RMQ(區間最值)問題。
阿新 • • 發佈:2018-11-21
Code:
#include<bits/stdc++.h> using namespace std; const int MAX = 2000; int n, m, x, y; int a[MAX + 5], lg[MAX + 5], maxn[MAX + 5][MAX + 5]; void solve(int *x) { for (int i = 1; i <= n; i++) { lg[i] = lg[i - 1]; if (1 << lg[i - 1] + 1 == i) lg[i]++; //cout << "lg[" << i << "]:" << lg[i] << endl; } for (int j = 1; j <= lg[n]; j++) { for (int i = 1; i + (1 << j) - 1 <= n; i++) { maxn[i][j] = max(maxn[i][j - 1], maxn[i + 1 << (j - 1)][j - 1]); } } } int askm(int l, int r) { int k = lg[r - l + 1]; return max(maxn[l][k], maxn[r - (1 << k) + 1][k]); } int main() { cin >> n >> m; for (int i = 1; i <= n; i++) { cin >> a[i]; maxn[i][0] = a[i]; } solve(a); //for (int i = 1; i <= n; ++i) //{ // for (int j = 0; j <= n; ++j) // { // cout << "max[" << i << "][" << j << "]:" << maxn[i][j] << " "; // } // cout << endl; //} for (int i = 1; i <= m; i++) { cin >> x >> y; cout << askm(x, y) << endl; } return 0; }
Analysis:
豎著讀maxn陣列:
Code2:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<cmath> using namespace std; int a[100001],f[100001][20]; inline int read(){ int x=0,f=1; char c=getchar(); for(;!isdigit(c);c=getchar()) if(c=='-') f=-1; for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f; } void RMQ(int N){ for(int j=1;j<=20;j++) for(int i=1;i<=N;i++) if(i+(1<<j)-1<=N) f[i][j]=max(f[i][j-1],f[i+(1<<(j-1))][j-1]); } int main(){ int N=read(),M=read(); for(int i=1;i<=N;i++) a[i]=read(); for(int i=1;i<=N;i++) f[i][0]=a[i]; RMQ(N); while(M--){ int i=read(),j=read(); int k=(int)(log((double)(j-i+1))/log(2.0)); printf("%d\n",max(f[i][k],f[j-(1<<k)+1][k])); } return 0; }