uva11235 RMQ
2015-02-10 12:01
113 查看
一段不减序列a1,a2...an,对于任意询问(i,j),回答ai,a(i+1)...aj中出现次数最多的值所出现的次数
按照不同值将序列分为若干段,记录相关数组,并用RMQ进行询问。
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100000+10;
const int maxlog=20;
//区间最大值
struct RMQ{
int d[maxn][maxlog];
void init(const vector<int>& A){
int n=A.size();
for(int i=0;i<n;i++) d[i][0]=A[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=0;i+(1<<j)-1<n;i++)
d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}
int query(int L,int R){
int k=0;
while((1<<(k+1))<=R-L+1) k++;//如果2^(k+1)<=R-L+1,那么k还可以加1
return max(d[L][k],d[R-(1<<k)+1][k]);
}
};
//a[i]:第i个数的值,num[i]:第i个数的编号,left[i]、right[i]:第i个数所在段的左右端点编号
int a[maxn],num[maxn],left[maxn],right[maxn];
RMQ rmq;
int main(){
int n,q;
//freopen("a.txt","r",stdin);
while(scanf("%d",&n)!=EOF){
if(!n) break; scanf("%d",&q);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
a
=a[n-1]+1;//哨兵
int start=-1;
vector<int> count;
for(int i=0;i<=n;i++)
if(i==0||a[i]>a[i-1]){//从新段开始,记录旧段的长度和其中每点的编号和左右端点位置
if(i>0){
count.push_back(i-start);
for(int j=start;j<i;j++)
num[j]=count.size()-1,left[j]=start,right[j]=i-1;
}
start=i;
}
rmq.init(count);
while(q--){
int L,R,ans;
scanf("%d%d",&L,&R); L--;R--;
if(num[L]==num[R]) ans=R-L+1;
else {
ans=max(R-left[R]+1,right[L]-L+1);
if(num[L]+1<num[R]) ans=max(ans,rmq.query(num[L]+1,num[R]-1));
}
printf("%d\n",ans);
}
}
return 0;
}
按照不同值将序列分为若干段,记录相关数组,并用RMQ进行询问。
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100000+10;
const int maxlog=20;
//区间最大值
struct RMQ{
int d[maxn][maxlog];
void init(const vector<int>& A){
int n=A.size();
for(int i=0;i<n;i++) d[i][0]=A[i];
for(int j=1;(1<<j)<=n;j++)
for(int i=0;i+(1<<j)-1<n;i++)
d[i][j]=max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
}
int query(int L,int R){
int k=0;
while((1<<(k+1))<=R-L+1) k++;//如果2^(k+1)<=R-L+1,那么k还可以加1
return max(d[L][k],d[R-(1<<k)+1][k]);
}
};
//a[i]:第i个数的值,num[i]:第i个数的编号,left[i]、right[i]:第i个数所在段的左右端点编号
int a[maxn],num[maxn],left[maxn],right[maxn];
RMQ rmq;
int main(){
int n,q;
//freopen("a.txt","r",stdin);
while(scanf("%d",&n)!=EOF){
if(!n) break; scanf("%d",&q);
for(int i=0;i<n;i++) scanf("%d",&a[i]);
a
=a[n-1]+1;//哨兵
int start=-1;
vector<int> count;
for(int i=0;i<=n;i++)
if(i==0||a[i]>a[i-1]){//从新段开始,记录旧段的长度和其中每点的编号和左右端点位置
if(i>0){
count.push_back(i-start);
for(int j=start;j<i;j++)
num[j]=count.size()-1,left[j]=start,right[j]=i-1;
}
start=i;
}
rmq.init(count);
while(q--){
int L,R,ans;
scanf("%d%d",&L,&R); L--;R--;
if(num[L]==num[R]) ans=R-L+1;
else {
ans=max(R-left[R]+1,right[L]-L+1);
if(num[L]+1<num[R]) ans=max(ans,rmq.query(num[L]+1,num[R]-1));
}
printf("%d\n",ans);
}
}
return 0;
}
相关文章推荐
- UVa 11235 / POJ 3368 Frequent values (想法题&RMQ线段树维护最长区间长度)
- POJ 3368—— Frequent values(频繁出现的数值UVA11235) RMQ
- RMQ算法 以及UVA 11235 Frequent Values(RMQ)
- UVa 11235 Frequent values (RMQ)
- UVa 11235 RMQ
- Frequent Values(UVa 11235) RMQ问题
- UVA - 11235 Frequent values RMQ问题
- UVA 11235 Frequent values(RMQ)
- Uva 11235 (RMQ)
- UVa 11235 频繁出现的数值(RMQ)
- RMQ问题 UVa 11235
- uva 11235(RMQ)
- UVA 11235 Frequent values 非递减序列 l r范围内 出现最多的数字次数 RMQ
- UVA 11235 Frequent Value RMQ
- UVA 11235 Frequent Values ---RMQ
- uva 11235 RMQ范围最大值
- UVA 11235-Frequent values-RMQ(st表)+游程编码
- uva 11235 Frequent Values(游程编码, RMQ)
- UVA 11235--Frequent values+RMQ问题
- UVA 11235 求区间连续数的众数 RMQ