UVA 11235 - Frequent values
嗯,RMQ问题。
纠结了好久,不过总算弄懂了
@。@
#include<cstdio> #include<algorithm> #include<vector> using namespace std; const int MAXN=100000+10; const int MANX_LOGN=20; int a[MAXN],left[MAXN],right[MAXN],num[MAXN]; struct RMQ { int d[MAXN][MANX_LOGN]; void init(const vector<int> &X) { int n=X.size(); for(int i=0;i<n;i++) d[i][0]=X[i]; for(int j=1; (1<<j) <=n;j++) for(int i=0; i + (1<<j) -1 <n; i++) d[i][j]=max(d[i][j-1],d[i + (1<<(j-1))][j-1] ); } int query(int L,int R) { int k=0; while( 1<<(k+1) <= R-L+1) k++; return max(d[L][k],d[R - (1<<k) +1][k]); } }; RMQ rmq; int main() { int n,q; while(scanf("%d", &n) ,n) { scanf("%d",&q); vector<int>cnt; for(int i=0;i<n;i++) scanf("%d",&a[i]); a[n]=a[n-1]+1; //最后一段通过它来标记 int begin=0,kind=0; for(int i=0;i<=n;i++) { if(a[i]>a[i-1]) //新的一段 { cnt.push_back(i-begin); for(int j=begin;j<i;j++) { num[j]=kind; left[j]=begin; right[j]=i-1; } begin=i; kind++; } } rmq.init(cnt); while(q--) { int L,R; scanf("%d%d",&L,&R); L--;R--; //本题从1开始 int ans; if(num[L]==num[R]) ans=R-L+1; else { ans=max(right[L]-L+1,R-left[R]+1); if(num[L]+1 < num[R]) ans=max(ans,rmq.query(num[L]+1,num[R]-1)); } printf("%d\n",ans); } } }
新 blog : www.hrwhisper.me