Frequent values UVA - 11235【RMQ 区间最大值】

稍微转化一下,将若干个相同的数合并成一个区间,权值为数的个数,构成一个新的数据
将这些数据求区间最值就可以了。

#include <bits/stdc++.h>
#define cl(a) memset(a,0,sizeof(a))
#define sc(x) scanf("%d",&x)
using namespace std;
const int maxn = 2e5+50;
int n,q;
int p=0;//表示有多少个不同的数
int cnt[maxn],value[maxn];// cnt[i] 表示 第i种数的个数,value[i] 表示第i种数的数值
int num[maxn],lef[maxn],rig[maxn];//num[i] 表示 第i个数对应的是第几种数
//lef[i]表示第i个数对应的区间的左端点,rig[i] 对应右端点
int a[maxn];//第i个数是什么
int d[maxn][30];// d[i][j] 表示以 i 为起点 长度为 2^j的区间内答案
void st()
{
	memset(d,0,sizeof(d));
    for(int i=0;i<=p;i++) d[i][0] = cnt[i];
    for(int j=1;(1<<j)<=p;j++)
    {
        for(int i=1; i+(1<<j)-1<=p;i++)
        {
            d[i][j] = max(d[i][j-1],d[i+(1<<(j-1))][j-1]);
        }
    }
}
int RMQ(int l,int r)
{
    int ans = 0;
    if(num[l]==num[r]) return r-l+1;
    ans = max(rig[l]-l+1,r-lef[r]+1);
    int k=0;
    int L = rig[l]+1;
    int R = lef[r]-1;
    if(num[L]>num[R]) return ans;
    if(num[L]==num[R]) return max(ans,R-L+1);
    while((1<<(k+1))<=(num[R]-num[L]+1)) k++;
    return max(ans,max(d[num[L]][k],d[num[R]-(1<<k)+1][k]));
}
int main()
{
	while(sc(n)&&n)
	{
	    //cout<<"n= "<<n<<endl;
	    p=0; cl(d); cl(num);cl(lef); cl(rig);cl(value);cl(cnt);
		sc(q);
/* memset(lef,0,sizeof(lef)); for(int i=1;i<=n;i++) { printf("%d %d\n",i,lef[i]); printf("num[i] = %d left[i] = %d right[i] = %d\n",num[i],lef[i],rig[i]); }*/
		a[0]=-0x3f3f3f3f;
		for(int i=1;i<=n;i++) sc(a[i]);
		for(int i=1;i<=n;i++)
		{
			if(a[i]!=a[i-1])
			{
				value[++p]=a[i];
				cnt[p]++;
				lef[i] = i;
			}
			else
			{
				cnt[p]++;
				lef[i]=lef[i-1];
			}
			num[i] = p;
		}
	/* for(int i=1;i<=p;i++) { printf("value = %d ,count = %d\n",value[i],cnt[i]); }*/
		for(int i=1;i<=n;i++) rig[i] = lef[i] + cnt[num[i]] - 1;
/* for(int i=1;i<=n;i++) { printf("num[i] = %d left[i] = %d right[i] = %d\n",num[i],lef[i],rig[i]); } */

		st();
		while(q--)
        {
            int x,y;
            sc(x);sc(y);
            printf("%d\n",RMQ(x,y));
        }
	}

	system("pause");
	return 0;
}

/* 10 3 -1 -1 1 1 1 1 3 10 10 10 2 3 1 10 5 10 0 */
全部评论

相关推荐

11-07 13:31
怀化学院 Java
勇敢牛牛不怕难:又疯一个
点赞 评论 收藏
分享
10-10 17:54
点赞 评论 收藏
分享
11-28 17:48
中山大学 C++
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务