传送门:http://poj.org/problem?id=3368
题意:输入一个n个元素排好序的序列,然后输入q个查询。每次查询一个区间,输出这个区间内出现最多次数的数字的次数,但是因为序列已经是排序好的,所以相等的数字一定是相邻的。所以用线段树,记录每个区间的最左边的数字,和最右边的数字,左边的连续长度,右边的连续长度,最长的总长度。然后查询的时候区间合并一下就可以搞了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <ctime>
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
#define PB push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define calm (l+r)>>1
const int INF=1e9+7;
const int maxn=100000;
int ll[maxn<<2],rr[maxn<<2],llen[maxn<<2],rlen[maxn<<2],sum[maxn<<2];
int n,m;
inline void pushup(int rt){
sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);
ll[rt]=ll[rt<<1]; rr[rt]=rr[rt<<1|1];
llen[rt]=llen[rt<<1]; rlen[rt]=rlen[rt<<1|1];
if(ll[rt<<1]==rr[rt<<1]){
if(rr[rt<<1]==ll[rt<<1|1]){
llen[rt]=llen[rt<<1]+llen[rt<<1|1];
}
}
if(ll[rt<<1|1]==rr[rt<<1|1]){
if(ll[rt<<1|1]==rr[rt<<1]){
rlen[rt]=rlen[rt<<1|1]+rlen[rt<<1];
}
}
if(rr[rt<<1]==ll[rt<<1|1]){
sum[rt]=max(sum[rt],rlen[rt<<1]+llen[rt<<1|1]);
}
sum[rt]=max(sum[rt],max(llen[rt],rlen[rt]));
}
void build(int l,int r,int rt){
ll[rt]=rr[rt]=llen[rt]=rlen[rt]=sum[rt]=0;
if(l==r){
int x;scanf("%d",&x);
ll[rt]=rr[rt]=x;
llen[rt]=rlen[rt]=sum[rt]=1;
return;
}
int m=calm;
build(lson);build(rson);
pushup(rt);
}
struct node{
int ll,rr,llen,rlen,sum;
node(){}
node(int ll,int rr,int llen,int rlen,int sum):ll(ll),rr(rr),llen(llen),rlen(rlen),sum(sum){}
};
node merge(node left,node right){
node ans;
ans.sum=max(left.sum,right.sum);
ans.ll=left.ll; ans.rr=right.rr;
ans.llen=left.llen; ans.rlen=right.rlen;
if(left.ll==left.rr){
if(left.rr==right.ll){
ans.llen=left.llen+right.llen;
}
}
if(right.ll==right.rr){
if(left.rr==right.ll){
ans.rlen=left.rlen+right.rlen;
}
}
if(left.rr==right.ll){
ans.sum=max(ans.sum,left.rlen+right.llen);
}
ans.sum=max(ans.sum,max(ans.llen,ans.rlen));
return ans;
}
node query(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return node(ll[rt],rr[rt],llen[rt],rlen[rt],sum[rt]);
}
int m=calm;
if(R<=m)return query(L,R,lson);
if(L>m)return query(L,R,rson);
return merge(query(L,R,lson),query(L,R,rson));
}
int main(){
//freopen("input.txt","r",stdin);
while(scanf("%d",&n)!=EOF){
if(n==0)break;
scanf("%d",&m);
build(1,n,1);
while(m--){
int L,R;scanf("%d%d",&L,&R);
printf("%d\n",query(L,R,1,n,1).sum);
}
}
//printf("[Run in %.1fs]\n",(double)clock()/CLOCKS_PER_SEC);
return 0;
}