题目链接:点击查看
题意:n个数,q次询问,区间(l,r) 连续出现的数最多的次数
题解:1、RMQ,保存区间的最大值,但先要把前面和a[l-1]相同的数去掉,对于特殊的数据也是会T的(比如n个数全都相同),这里主要是学习下方法;
2、线段树维护区间最大值,直接就是nlog(n)
RMQ:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1e5+10;
int dp[N][20];
int n,q,a[N];
int main()
{
while(~scanf("%d",&n)&&n)
{
scanf("%d",&q);
a[0]=-1000000;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(i==1||a[i]!=a[i-1]) dp[i][0]=1;
else dp[i][0]=dp[i-1][0]+1;
}
for(int j=1;j<20;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
dp[i][j]=max(dp[i][j-1],dp[i+(1<<(j-1))][j-1]);
int l,r,cnt;
int ans;
while(q--)
{
scanf("%d%d",&l,&r);
ans=0;
while(l<=r&&a[l]==a[l-1]) l++,ans++;
if(l<=r)
{
cnt=(int)log2(r-l+1);
ans=max(ans,max(dp[l][cnt],dp[r-(1<<cnt)+1][cnt]));
}
printf("%d\n",ans);
}
}
return 0;
}
线段树区间合并,注意判断查询时区间合并
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=1e5+10;
struct node{
int l,r;
int maxx;
int ml,mr;
}tree[N<<2];
int n,q,a[N];
void pushup(int cur)
{
tree[cur].ml=tree[cur<<1].ml;
if(tree[cur<<1].ml==tree[cur<<1].r-tree[cur<<1].l+1&&a[tree[cur<<1].l]==a[tree[cur<<1|1].l])
tree[cur].ml=tree[cur<<1].ml+tree[cur<<1|1].ml;
tree[cur].mr=tree[cur<<1|1].mr;
if(tree[cur<<1|1].mr==tree[cur<<1|1].r-tree[cur<<1|1].l+1&&a[tree[cur<<1|1].r]==a[tree[cur<<1].r])
tree[cur].mr=tree[cur<<1|1].mr+tree[cur<<1].mr;
tree[cur].maxx=max(tree[cur<<1].maxx,tree[cur<<1|1].maxx);
if(a[tree[cur<<1].r]==a[tree[cur<<1|1].l])
tree[cur].maxx=max(tree[cur].maxx,tree[cur<<1].mr+tree[cur<<1|1].ml);
}
void build(int l,int r,int cur)
{
tree[cur].l=l;
tree[cur].r=r;
if(l==r)
{
tree[cur].maxx=1;
tree[cur].ml=tree[cur].mr=1;
return;
}
int mid=(r+l)>>1;
build(l,mid,cur<<1);
build(mid+1,r,cur<<1|1);
pushup(cur);
// cout<<l<<" "<<r<<" "<<tree[cur].maxx<<" "<<tree[cur].ml<<" "<<tree[cur].mr<<endl;;
}
int query(int pl,int pr,int cur)
{
// cout<<tree[cur<<1|1].l<<" "<<tree[cur].r<<endl;
if(pl<=tree[cur].l&&tree[cur].r<=pr)
return tree[cur].maxx;
int res=0;
if(pr<=tree[cur<<1].r)
return query(pl,pr,cur<<1);
else if(pl>=tree[cur<<1|1].l)
return query(pl,pr,cur<<1|1);
else
{
res=max(res,query(pl,pr,cur<<1));
res=max(res,query(pl,pr,cur<<1|1));
if(a[tree[cur<<1].r]==a[tree[cur<<1|1].l])
res=max(res,min(pr,tree[cur<<1|1].l+tree[cur<<1|1].ml-1) - max(pl,tree[cur<<1].r-tree[cur<<1].mr+1) + 1);
return res;
}
}
int main()
{
while(~scanf("%d",&n)&&n)
{
scanf("%d",&q);
a[0]=-1000000;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
build(1,n,1);
int l,r;
while(q--)
{
scanf("%d%d",&l,&r);
printf("%d\n",query(l,r,1));
}
}
return 0;
}