**1.题目解析可见《训练指南》P198**
**2代码:**
~~~
#include<cstdio>
#include<cstring>
#include<cmath>
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)>(b)?(a):(b))
#define N 100005
#define INF 1<<30
using namespace std;
int a[N];
int value[N],cnt[N],num[N],L[N],R[N];
int ST[N][20];
int n,q;
int k;
void make_ST()//对cnt[]预处理
{
for(int i=1;i<=k;i++)
{
ST[i][0]=cnt[i];
}
for(int j=1;(1<<j)<=n;j++)
{
for(int i=1;(i+(1<<j)-1)<=n;i++)
{
ST[i][j]=Max(ST[i][j-1],ST[i+(1<<(j-1))][j-1]);
}
}
}
int Query(int l,int r)
{
if(l>r)
return 0;
else
{
int kk=floor(log2(r-l+1));
return Max(ST[l][kk],ST[r-(1<<kk)+1][kk]);
}
}
int main()
{
while(scanf("%d",&n)&&n)
{
scanf("%d",&q);
k=0;
value[0]=INF;
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
if(a[i]!=value[k])
{
R[k]=i;
value[++k]=a[i];
L[k]=i-1;
cnt[k]=1;
num[i]=k;
}
else
{
cnt[k]++;
num[i]=num[i-1];
}
}
R[k]=n+1;
make_ST();
while(q--)
{
int l,r;
scanf("%d%d",&l,&r);
if(num[l]==num[r])
{
printf("%d\n",r-l+1);
}
else
{
int tmp=Max(R[num[l]]-l,r-L[num[r]]);
int ans=Max(tmp,Query(num[l]+1,num[r]-1));
printf("%d\n",ans);
}
}
}
return 0;
}
~~~
- 前言
- The 12th Zhejiang Provincial Collegiate Programming Contest - D
- 用邻接表存储n个顶点m条弧的有向图
- hdu 5289 Assignment(给一个数组,求有多少个区间,满足区间内的最大值和最小值之差小于k)
- hdu 1358 Period(给定一个字符串,求有多少个前缀(包括自己本身),它是由k(k&gt;2,并且尽量大)个循环节组成的)
- hdu 1806 Frequent values(给定一个非降序数组,求任意区间内出现次数最多的数的次数)
- poj 3264 Balanced Lineup(查询区间最大值与最小值的差)
- HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
- HDU 1015 Safecracker(第一次用了搜索去遍历超时,第二次用for循环可以了,思路一样的)
- HDU 1016 Prime Ring Problem(DFS)
- HDU 1026 Ignatius and the Princess I(BFS+记录路径)
- HDU 1072 Nightmare(BFS)
- HDU 1237 简单计算器(后缀式+栈)