| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
哪位给点测试数据#include<iostream>
#include<cmath>
using namespace std;
//rmq
//题意:给定一个非递减的序列,a1,a2,a3....an,给出一系列询问RMQ[i,j],问在区间[i,j]上出现频率最高的数字
//这个最高相当于RMQ中的最大,那么问题的关键就成了如何将他转化成可解的RMQ模型
//这里有个很关键的信息,就是非递减,那么数字都是连续出现,出了这段,在其他地方便不可能出现了
//那么我们可以预处理下每个数字的左右边界以及频数,那么在区间查询时根据这个可以计算出当前区间内,某个数的频数,想想是不是如此
//这样离散化操作后给定一个区间,那么区间中有哪些数,数的频率都确定下来了
//考率中间的连续段,做RMQ,然后取最大和左右剩余的区间比较,若就在某个区间内部单独考虑
int n,q,len;//len代表区间段的个数
int a[100005];
int l[100005],r[100005],h[100005];//l,r,h,记录离散后的区间段起始,结束,频数 注意下标表示的是区间段
int ll[100005],rr[100005];//记录具体每个数的起始,结束 具体到原数列每一项
int dp[20][100005];
int d[100005];
int MAX(int x,int y)
{
return x>y?x:y;
}
void RMQ()//只对连续的完整的段进行处理,这里吧段看成是一个元素
{
int i,j;
for(i=1;i<=len;i++)dp[0][i]=h[i];
for(j=1;j<=int(log((double)n)/log(2.0));j++)
{
for(i=1;i+(1<<j)-1<=len;i++)
{
dp[j][i]=MAX(dp[j-1][i],dp[j-1][i+(1<<(j-1))]);
}
}
}
int query(int i,int j)//参数表示左右两段的区间编号
{
int k=int(log((double)(j-i+1))/log(2.0));//获得步长
return MAX(dp[k][i],dp[k][j-(1<<k)+1]);
}
int main()
{
int i,j,k,c,x,y,t,left,right,xx,yy,max;
while(scanf("%d",&n)!=EOF)
{
if(n==0)break;
scanf("%d",&q);
for(i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
a[n+1]=200000;
len=1;
for(i=1;i<=n;i++)
{
l[len]=i;
c=0;
while(a[i]==a[i+1]){i++;c++;}
r[len]=l[len]+c;
h[len]=c+1;
len++;
}
len--;
/* for(i=1;i<=len;i++)
{
cout<<"left="<<l[i]<<endl;
cout<<"right="<<r[i]<<endl;
}*/
for(i=1;i<=len;i++)
{
for(j=l[i];j<=r[i];j++)//把区间段的数处理好
{
a[j]=h[i];//把每个位置修改成了频数样例编程了2,2,4,4,4,4,1,3,3,3
ll[j]=l[i];//1,1,3,3,3,3,7,8,8,8
rr[j]=r[i];//2,2,6,6,6,6,7,10,10,10
d[j]=i;// 1,1,2,2,2,2,3,4,4,4 编号
}
}
// for(i=1;i<=n;i++)测试数据
RMQ();
for(i=1;i<=q;i++)
{
scanf("%d%d",&x,&y);
// cout<<query(x,y)<<endl;
if(x>y){t=x;x=y;y=t;}
if(ll[x]==ll[y])//表示在同一段
{
printf("%d\n",y-x+1);
continue;
}
xx=0;
yy=0;
// cout<<"x="<<x<<" y="<<y<<endl;
if(ll[x]<x){xx=rr[x]-x+1;x=rr[x]+1;}//获取左段,更新边界
if(rr[x]>y){yy=y-ll[y]+1;y=ll[x]-1;}//获取右段,更新边界
max=0;
// cout<<"x="<<x<<" y="<<y<<endl;
if(x<y)max=query(d[x],d[y]);
// cout<<d[x]<<" "<<d[y]<<endl;
// cout<<"max="<<max<<endl;
max=MAX(max,xx);
max=MAX(max,yy);
printf("%d\n",max);
}
}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator