UVa 11235 頻繁出現的數值
阿新 • • 發佈:2018-12-13
劉汝佳書上看到的問題,沒有看題解做了一下,直接AC了,不多說了,直接上程式碼總的來說RMQ查詢左部最大,右部最大,和交叉部最大的三者中的最大值
#include <utility> #include <cstdio> #include <map> #include <algorithm> using namespace std; map<int, pair<int,int>>mmp; int v[100005][20],vv[100005]; int n,q; void m_build(){ for(int j=1;(1<<j)<=n;j++) for(int i=1;i+(1<<j)-1<=n;i++){ int t=0; if(vv[i+(1<<(j-1))-1]==vv[i+(1<<(j-1))]) t=min(mmp[vv[i+(1<<(j-1))-1]].second,i-1+(1<<j))-max(mmp[vv[i+(1<<(j-1))-1]].first,i)+1; v[i][j]=max(t,max(v[i][j-1],v[i+(1<<(j-1))][j-1])); } } int m_find(int l,int r){ int k=0; while((1<<(k+1))<=r-l+1)k++; int t=0; if(vv[r-(1<<k)+1]==vv[l+(1<<k)-1]) t=min(r,mmp[vv[r-(1<<k)+1]].second)-max(l,mmp[vv[r-(1<<k)+1]].first)+1; return max(t,max(v[l][k],v[r-(1<<k)+1][k])); } int main() { while (scanf("%d",&n)!=EOF) { if(n==0) break; scanf("%d",&q); for(int i=1;i<=n;i++) v[i][0]=1; int s=1; scanf("%d",&vv[1]); for(int i=2;i<=n;i++){ scanf("%d",&vv[i]); if(vv[i]!=vv[i-1]){ pair<int, int>x; x.first=i-s; x.second=i-1; mmp[vv[i-1]]=x; s=1; } else s++; } pair<int, int>x; x.first=n-s+1; x.second=n; mmp[vv[n]]=x; m_build(); while (q--) { int l,r; scanf("%d%d",&l,&r); printf("%d\n",m_find(l,r)); } } return 0; }