您的位置:首页 > 产品设计 > UI/UE

【RMQ】 UVA 11235 Frequent values

2014-11-08 09:22 387 查看
大白例题

题意:给出一个不递减序列 

 再给出多个询问 l  r 

输出 l - r 区间内 出现最多的数的次数

同段表示值相同的一段

计算每个位置的 left   :同段中最左边位置

right  :同段中最右边位置

num  :第几段

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include <map>
#define cler(arr, val) memset(arr, val, sizeof(arr))
typedef long long LL;
const int MAXN = 240000;
const int MAXM = 140000;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
int dp[MAXN][22],val[MAXN],c[MAXN];
int A[MAXN*2];
int n,m,num;
struct node
{
int left,right,num;
}p[MAXN];
void RMQ_init()
{
for(int i=0;i<num;i++)
dp[i][0]=c[i];
for(int i=1;(1<<i)<=num;i++)
for(int j=0;j+(1<<i)-1<num;j++)
dp[j][i]=max(dp[j][i-1],dp[j+(1<<(i-1))][i-1]);
}
int RMQ(int l,int r)
{
int k=(int)(log(double(r-l+1))/log((double)2));
return max(dp[l][k],dp[r-(1<<k)+1][k]);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
while(cin>>n,n)
{
cin>>m;
cler(c,0);
num=-1;
int x;
for(int i=0;i<n;i++)
{
scanf("%d",&A[i]);
if(i==0||A[i-1]!=A[i])
{
num++;
val[num]=A[i];
x=i;
}
c[num]++;
p[i].num=num;
p[i].left=x;
}
num++;
for(int i=0;i<n;i++)
{
p[i].right=p[i].left+c[p[i].num]-1;
}
RMQ_init();
int a,b;
for(int i=0;i<m;i++)
{
scanf("%d %d",&a,&b);
a--,b--;
if(p[a].num==p[b].num)
{
printf("%d\n",b-a+1);
continue;
}
// printf("p[a].right-a+1:%d\n",p[a].right-a+1);
// printf("b-p[b].left+1 :%d\n",b-p[b].left+1);
int ans=max(p[a].right-a+1,b-p[b].left+1);
if(p[a].num+1<=p[b].num-1)
ans=max(ans,RMQ(p[a].num+1,p[b].num-1));
printf("%d\n",ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: