【RMQ】 UVA 11235 Frequent values

来源:互联网 发布:淘宝衣服进货渠道 编辑:程序博客网 时间:2024/05/17 21:38

大白例题

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

 再给出多个询问 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;}


0 0