POJ 3368

来源:互联网 发布:mysql从excel导入数据 编辑:程序博客网 时间:2024/06/15 23:32
题意: 给你一组数列, 查询区间内有出现次数最多的数的频数

RMQ ,

对于一个区间, 分为两部分, 从  L 开始连续到  T  , T + 1 到  R

显然 答案为  MAX (T – L + 1 , RMQ ( T+1, R))

对于 T, 可以先预处理出位置 Pos

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100000 + 131;int Pos[maxn];int Num[maxn];int d[maxn][30];int Fun[maxn];int n, m;void RMQ_init(){    for(int i = 0; i < n; ++i) d[i][0] = Fun[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 RMQ(int L, int R){    int k = 0;    while((1<<(k+1)) <= R-L+1) k++;    return max(d[L][k], d[R-(1<<k)+1][k]);}int main(){    while(scanf("%d",&n) != EOF)    {        if(n == 0) break;        scanf("%d",&m);        for(int i = 0; i < n; ++i) scanf("%d",&Num[i]);        for(int i = 0; i < n; ++i)        {            if(i == 0) Fun[i] = 1;            else            {                if(Num[i] == Num[i-1]) Fun[i] = Fun[i-1] + 1;                else Fun[i] = 1;            }        }        //for(int i = 0; i < n; ++i) cout << Fun[i];        //cout <<endl;        ////////////////////////        int Now = Num[n-1], pos = n-1;        for(int i = n-1; i >= 0; --i)        {            if(Num[i] == Now)                Pos[i] = pos;            else            {                Now = Num[i];                Pos[i] = i;                pos = i;            }        }        /*for(int i = 0; i < n; ++i) cout << Pos[i];        cout <<endl;*/        //////////////////////////        RMQ_init();        //cout << RMQ(2,5) <<endl;        int l, r;        for(int i = 0; i < m; ++i)        {            scanf("%d%d",&l,&r);            l--, r--;            int t = Pos[l];            //cout << t << endl;            if(t >= r)            {                printf("%d\n",r-l+1);                continue;            }            else                printf("%d\n", max(t-l+1,RMQ(t+1,r)));        }    }}
0 0
原创粉丝点击