Description:
给出一个序列,a1,a2……a3,你的任务是对于一系列询问(i,j),回答ai,……aj中出现次数最多的值所出现的次数。
思路:
这题可以用ST算法,但是没想到主要的编码困难是在数据的预处理。
用结构体struct node{ int value,cnt; node(int v,int c):value(v),cnt(c){} };
来储存某一段的数字的值,以及出现的次数。
用结构体struct pos{ int index,left,right; pos(int index,int l,int r):index(index),left(l),right(r){} };
储存某个位置所在段的编号和这一段左右端点的位置
查询时分情况处理:
①L,R在同一段
答案就是 L-R+1
②L,R中间加住了2段及以上
ans应该在
x1 = index( L ).right - L+1
x2 = R-index( R ).left+1
x3 = ST(index( L )+1,index( R )-1)
三者挑出。
#include<stdio.h>
#include<iostream>
#include<cmath>
#include<math.h>
#include<string>
#include<string.h>
#include<algorithm>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#define ms0(a) memset(a,0,sizeof(a))
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 1e5+10;
int n,q,d[maxn][20];
struct node{
int value,cnt;
node(int v,int c):value(v),cnt(c){}
};
struct pos{
int index,left,right;
pos(int index,int l,int r):index(index),left(l),right(r){}
};
void ST_init(const vector<int>& A)
{
int n = (int)A.size();
for(int i=0;i<n;i++) d[i][0]=A[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 ST(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]);
}
int main(){
while(~scanf("%d",&n)&&n)
{
vector<node> num;vector<pos> a;
vector<int> A;
ms0(d);
int x,y;
scanf("%d",&q);
scanf("%d",&x);
num.push_back(node(x,1));
for(int i=2;i<=n;i++)
{
scanf("%d",&y);
if(x==y){
num[num.size()-1].cnt++;
}
else{
num.push_back(node(y, 1));
}
x=y;
}
int count = 0;
a.push_back(pos(0,0,0));//填充0位置
int size = num[0].cnt; count++;
for(int j=1;j<=size;j++)
a.push_back(pos(count,1,size));
for(int i=1;i<num.size();i++)
{
int size = num[i].cnt; count++;
int lastRight = a[a.size()-1].right;
for(int j=1;j<=size;j++)
{
a.push_back(pos(count,lastRight+1, lastRight+size));
}
}
for(int i=0;i<num.size();i++)
A.push_back(num[i].cnt);
ST_init(A);
for(int i=1;i<=q;i++)
{
int l,r;
scanf("%d%d",&l,&r);
if(a[l].index==a[r].index)
printf("%d\n",r-l+1);
else
{
int ans = max(a[l].right-l+1,r-a[r].left+1);
int L = a[l].index+1,R = a[r].index-1;
ans = max(ans,L<=R?ST(L-1, R-1):0);
printf("%d\n",ans);
}
}
}
return 0;
}