【RMQ】 UVA 11235 Frequent values
大白例题
题意:给出一个不递减序列
再给出多个询问 l r
输出 l - r 区间内 出现最多的数的次数
同段表示值相同的一段
计算每个位置的 left :同段中最左边位置
right :同段中最右边位置
num :第几段
#include <cstdio> #include <cstring> #include <cstdlib> #include <string> #include <iostream> #include <algorithm> #include <sstream> #include <cmath> using namespace std; #include <queue> #include <stack> #include <vector> #include <deque> #include <map> #define cler(arr, val) memset(arr, val, sizeof(arr)) typedef long long LL; const int MAXN = 240000; const int MAXM = 140000; const int INF = 0x3f3f3f3f; const int mod = 1000000007; int dp[MAXN][22],val[MAXN],c[MAXN]; int A[MAXN*2]; int n,m,num; struct node { int left,right,num; }p[MAXN]; void RMQ_init() { for(int i=0;i<num;i++) dp[i][0]=c[i]; for(int i=1;(1<<i)<=num;i++) for(int j=0;j+(1<<i)-1<num;j++) dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]); } int RMQ(int l,int r) { int k=(int)(log(double(r-l+1))/log((double)2)); return max(dp[l][k],dp[r-(1<<k)+1][k]); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); #endif while(cin>>n,n) { cin>>m; cler(c,0); num=-1; int x; for(int i=0;i<n;i++) { scanf("%d",&A[i]); if(i==0||A[i-1]!=A[i]) { num++; val[num]=A[i]; x=i; } c[num]++; p[i].num=num; p[i].left=x; } num++; for(int i=0;i<n;i++) { p[i].right=p[i].left+c[p[i].num]-1; } RMQ_init(); int a,b; for(int i=0;i<m;i++) { scanf("%d %d",&a,&b); a--,b--; if(p[a].num==p[b].num) { printf("%d\n",b-a+1); continue; } // printf("p[a].right-a+1:%d\n",p[a].right-a+1); // printf("b-p[b].left+1 :%d\n",b-p[b].left+1); int ans=max(p[a].right-a+1,b-p[b].left+1); if(p[a].num+1<=p[b].num-1) ans=max(ans,RMQ(p[a].num+1,p[b].num-1)); printf("%d\n",ans); } } return 0; }