POJ--3368--Frequent values【RMQ】

来源:互联网 发布:plc步进电机编程实例 编辑:程序博客网 时间:2024/04/27 00:05

链接:http://poj.org/problem?id=3368

题意:给你一个序列,n个数,序列是有序的,q个询问,问区间(l,r)中出现频率最高的数字出现了几次。


思路:因为序列是有序的,可以把序列相同部分合并,然后存成一个新的数组,并增加一个值num表示数字出现的次数,找区间(l,r)中出现频率最高的数字,就是找num的最大值了,区间最大值,RMQ可做,线段树也可做,我用RMQ做的。注意(l,r)没有取完它们表示的数字区间时的特判。


#include<cstring>#include<string>#include<fstream>#include<iostream>#include<iomanip>#include<cstdio>#include<cctype>#include<algorithm>#include<queue>#include<map>#include<set>#include<vector>#include<stack>#include<ctime>#include<cstdlib>#include<functional>#include<cmath>using namespace std;#define PI acos(-1.0)#define MAXN 2001000#define eps 1e-7#define INF 0x7FFFFFFF#define LLINF 0x7FFFFFFFFFFFFFFF#define seed 1313131#define MOD 1000000007#define ll long long#define ull unsigned ll#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1struct node{    int l,r,num;}bb[101000];int pos[101000];int aa[101000];int maxsum[101000][25];void RMQ(int num){    int i,j;    for(i=0;i<=num;i++){        maxsum[i][0] = bb[i].num;    }    for(j=1;j<20;j++){        int t = 1 << j;        for(i=1;i+t-1<=num;i++){            maxsum[i][j] = max(maxsum[i][j-1], maxsum[i+(1<<(j-1))][j-1]);        }    }}int main(){    int n,q,i,j,cnt;    int a,b;    while(scanf("%d",&n),n){        scanf("%d",&q);        cnt = 1;        scanf("%d",&aa[1]);        pos[1] = cnt;        bb[cnt].num = 1;        bb[cnt].l = 1;        for(i=2;i<=n;i++){            scanf("%d",&aa[i]);            if(aa[i]==aa[i-1]){                pos[i] = cnt;                bb[cnt].num++;            }            else{                bb[cnt].r = i - 1;                cnt++;                pos[i] = cnt;                bb[cnt].l = i;                bb[cnt].num = 1;            }        }        bb[cnt].r = n;        RMQ(cnt);        while(q--){            scanf("%d%d",&a,&b);            if(pos[a]==pos[b])  printf("%d\n",b-a+1);            else if(pos[b]-pos[a]==1)   printf("%d\n",max(bb[pos[a]].r-a+1,b-bb[pos[b]].l+1));            else{                int ans = 0;                ans = max(bb[pos[a]].r-a+1,b-bb[pos[b]].l+1);                b = pos[b] - 1;                a = pos[a] + 1;                int k = (int)(log((double)b-a+1)/log(2.0));                int t2 = max(maxsum[a][k],maxsum[b-(1<<k)+1][k]);                ans = max(ans,t2);                printf("%d\n",ans);            }        }    }    return 0;}


0 0