https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2176
Given a non-decreasing sequence Ai, you only need to support one operation: finding the number of occurrences of the most numbers in an interval.
Thought: st table. First, the original sequence A should be divided into blocks. If we synthesize an equal number and regard the number of the blocks as the size of the block, then the number of numbers that appear most in an interval of the original query sequence is not equal to the maximum value of the new query sequence. Of course, we also need to record some other information when merging. See the code comments for details.
#include <bits/stdc++.h> #define INF 0x3f3f3f3f using namespace std; int a[100005];//Original sequence int v[100005];//The value of the merged sequence int cnt[100005];//Number of occurrences of each value in the merged sequence int id[100005];//The position of the number i in the sequence after merging int l[100005];//The first position is the end point of the left interval after the merger int r[100005];//The first position is at the end of the right interval after merger. int d[100005][30];//st table int MAX=1; void RMQ_init() { int t=log2(MAX); for(int i=1;i<=MAX;i++) d[i][0]=cnt[i]; for(int j=1;j<=t;j++) { for(int i=1;i+(1<<j)-1<=MAX;i++) d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]); } } int RMQ(int v1,int v2) { int t=log2(v2-v1+1); return max(d[v1][t],d[v2-(1<<t)+1][t]); } int main() { int t1,t2; int temp; while(~scanf("%d",&t1)&&t1) { scanf("%d",&t2); for(int i=1;i<=t1;i++) scanf("%d",&a[i]); MAX=1; v[1]=a[1]; cnt[1]=1; id[1]=1; l[1]=1; for(int i=2;i<=t1;i++) { if(a[i]!=v[MAX]) { v[++MAX]=a[i]; cnt[MAX]=1; id[i]=MAX; l[i]=i; for(int k=i-1;k>=1;k--) { if(MAX>=2&&a[k]!=v[MAX-1]) break; r[k]=i-1; } } else { cnt[MAX]++; id[i]=MAX; l[i]=l[i-1]; } if(i==t1) { for(int k=t1;k>=1;k--) { if(MAX>=2&&a[k]!=v[MAX-1]) break; r[k]=i; } } } int v1,v2; RMQ_init(); while(t2--) { scanf("%d%d",&v1,&v2); if(id[v1]==id[v2])//The same block printf("%d\n",v2-v1+1); else if(id[v2]-id[v1]==1)//Adjacent blocks printf("%d\n",max(r[v1]-v1+1,v2-l[v2]+1)); else//Number of Phase Blocks >= 2 printf("%d\n",max(max(r[v1]-v1+1,v2-l[v2]+1),max(v2-l[v2]+1,RMQ(id[v1]+1,id[v2]-1)))); } } return 0; }