题目大意说给出一系列数,这列数是不降的,然后任意给出一个区间[i,j],让你求出那个重复次数最多的数的出现次数。由于给出的查询次数很多,我就考虑用RMQ来解,但是这个不能直接套用模板,因为加入我们对区间[i,j]进行查询,如果从k处分开取两边区间的最大的重复次数是不一定正确的,因为分开的那个地方可能把实际重复次数最多的那个数一分为二,这样求出的就不是最大的了,所以只需要多加一个判断,从分开出往左往右循环找到最大的重复次数,看这个数是否大于我们当前得到的那个数(这个数是取左右区间的最大值)。
代码如下:
#include#include #include using namespace std; const int N=100001; int a[N]; struct node{ int num,cnt; }; node m[N][18]; void initrmq(int n) { int i,j; for(i=0;i m[i+(1<<(j-1))][j-1].cnt) m[i][j].cnt=m[i][j-1].cnt; else m[i][j].cnt=m[i+(1<<(j-1))][j-1].cnt; //多一个判断,看断开的那个数是否是重复次数最多的 int tmp=a[i+(1<<(j-1))-1]; int x=i+(1<<(j-1))-1,y=x,r=i+(1< =i && (a[x]==tmp)) x--; while(y<=r && (a[y]==tmp)) y++; int tmpcnt=y-x-1; if(tmpcnt > m[i][j].cnt) { m[i][j].cnt=tmpcnt; } } } } int queryrmq(int i,int j) { int k=(int)(log((j-i+1)*1.0)/(log(2.0))),rscnt; if(m[i][k].cnt < m[j-(1< =i && (a[x]==tmp)) x--; while(y<=j && (a[y]==tmp)) y++; int tmpcnt=y-x-1; // cout<<"new "< <<" "< <<" "< < rscnt) rscnt=tmpcnt; return rscnt; } int main() { int n,q,i,ans,l,r; while(1) { scanf("%d",&n); if(!n) break; scanf("%d",&q); for(i=0;i