您的位置:首页 > 其它

UVa 11235 频繁出现的数值

2015-05-02 13:14 393 查看
题意描述:给出一个非降序列的整数数组a1,a2,...an。你的任务是对于一系列询问(i,j),回答ai,....aj,中出现次数最多的次数。

RMQ,以前看过但是没敲过,自己没看书敲了一下,感觉还挺顺。虽然还是wa了两次,第一次因为少了个中括号,第二次因为i-j的数的个数写成了j-i。

code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
const int maxn=100000+10;

int length[maxn],origin[maxn],terminal[maxn],belong[maxn],maxin[maxn][100];//[,)
int present;
void init(){
present=0;
memset(length,0,sizeof(length));
memset(origin,0,sizeof(origin));
memset(terminal,0,sizeof(terminal));
memset(belong,0,sizeof(belong));
}

void pretreatment(int* sequence){
for(int i=0;i<=present;i++) maxin[i][0]=length[i];
for(int j=1;(1<<j)<=(present+1);j++)
for(int i=0;i+(1<<j)-1<=present;i++)
maxin[i][j]=max(maxin[i][j-1],maxin[i+(1<<(j-1))][j-1]);
}

int query(int l,int r){
int k=0;
if(r>=l){
while((1<<(k+1))<=r-l+1)k++;
return max(maxin[l][k],maxin[r-(1<<k)+1][k]);
}
else return 0;
}

int main(){
int n,q;
while(scanf("%d",&n)==1&&n!=0){
scanf("%d",&q);
init();
int x,y;
scanf("%d",&x);
length[present]++;
terminal[present]++;
for(int i=1;i<n;i++){
scanf("%d",&y);
if(y==x){ length[present]++;
terminal[present]++;
belong[i]=present;
}
else {
x=y;
present++;
length[present]=1;
origin[present]=i;
terminal[present]=i+1;
belong[i]=present;
}
}
pretreatment(length);
//queary
for(int i=0;i<q;i++){
int a,b;
int ans;
scanf("%d%d",&a,&b);
a--;
b--;
if(belong[a]==belong[b])ans=b-a+1;
else{ ans=terminal[belong[a]]-a;
ans=max(ans,b-origin[belong[b]]+1);
ans=max(ans,query(belong[a]+1,belong[b]-1));
}
printf("%d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: