POJ3668——Frequent values(线段树,RMQ,ST表)

来源:互联网 发布:php 判断是否正整数 编辑:程序博客网 时间:2024/05/16 17:07

Frequent values
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu
Submit Status Practice POJ 3368

Description

You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i andj (1 ≤ i ≤ j ≤ n). For each query, determine the most frequent value among the integers ai , ... , aj.

Input

The input consists of several test cases. Each test case starts with a line containing two integers n and q (1 ≤ n, q ≤ 100000). The next line contains nintegers a1 , ... , an (-100000 ≤ ai ≤ 100000, for each i ∈ {1, ..., n}) separated by spaces. You can assume that for each i ∈ {1, ..., n-1}: ai ≤ ai+1. The following q lines contain one query each, consisting of two integers i and j (1 ≤ i ≤ j ≤ n), which indicate the boundary indices for the 
query.

The last test case is followed by a line containing a single 0.

Output

For each query, print one line with one integer: The number of occurrences of the most frequent value within the given range.

Sample Input

10 3-1 -1 1 1 1 1 3 10 10 102 31 105 100

Sample Output

143



题意:找一段区间内出现最多的树的个数

思路:我们只关心每个数的个数。所以把每个数的个数用一个新数组保存起来。查询的时候查询一下区间最大值即可。

RMQ查询可以用线段树树状数组或者ST表。其中ST表的查询是O(1)的复杂度。

代码提供了ST表和线段树的函数。


#include <cmath>#include <cstring>#include <cstdio>#include <vector>#include <string>#include <algorithm>#include <string>#include <map>#include <queue>#include <set>#include <stack>using namespace std;#define MAXN 500010#define LEN 200010#define INF 1e9+7#define MODE 1000000#define pi acos(-1)#define g 9.8typedef long long ll;#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int n,m,q;struct node{    int num;    int len;    int first;    int last;};node ans[MAXN];int a[MAXN];int b[MAXN];int F[MAXN][20];void SparseTable(){for (int i = 0;i<m;i++){F[i][0]=ans[i].len;}int nLog = int(log(double(m))/log(2.0));for (int j = 1;j <= nLog;j++){for (int i = 0;i < m;i++){if ((i + (1 << j) - 1) < m){if(F[i][j-1]>F[i+(1<<(j-1))][j-1])                {                    F[i][j]=F[i][j-1];                }                else                {                    F[i][j]=F[i+(1<<(j-1))][j-1];                }}}}}int RMQ(int nStart,int nEnd){int nLog = (int)(log(double(nEnd - nStart + 1)/log(2.0)));return max(F[nStart][nLog],F[nEnd - (1 << nLog) + 1][nLog]);}#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1int sum[MAXN<<2];void PushUp(int rt){sum[rt]=max(sum[rt<<1],sum[rt<<1|1]);}void build(int l,int r,int rt){if(l==r){sum[rt]=ans[l].len;return;}int m=(l+r)>>1;build(lson);build(rson);PushUp(rt);}int query(int L,int R,int l,int r,int rt){if(L<=l&&r<=R)return sum[rt];int m=(l+r)>>1;int ret=0;if(L<=m)ret=max(ret,query(L,R,lson));if(R>m)ret=max(ret,query(L,R,rson));return ret;}int main(){    //freopen("out.txt","w",stdout);    while(scanf("%d)",&n))    {        if(n==0)            break;        scanf("%d",&q);        for(int i=0;i<n;i++)        {            scanf("%d",a+i);            ans[i].len=0;        }        m=0;        ans[0].num=a[0];        ans[0].len=1;        ans[0].first=0;        for(int i=1;i<n;i++)        {            if(a[i]==a[i-1])            {                ans[m].len++;                b[i]=m;            }            else            {                ans[m].last=i-1;                m++;                b[i]=m;                ans[m].num=a[i];                ans[m].len=1;                ans[m].first=i;            }        }        ans[m++].last=n-1;        build(0,m-1,1);        while(q--)        {            int r,l;            int R,L;            scanf("%d%d",&l,&r);            l--;            r--;            L=b[l];            R=b[r];            if(R==L)            {                printf("%d\n",r-l+1);                continue;            }            if(ans[L].first<l)                L++;            if(ans[R].last>r)                R--;            if(R<L)            {                int res=-1;                res=max(res,r-ans[R+1].first+1);                res=max(res,ans[L-1].last-l+1);                printf("%d\n",res);                continue;            }            int res=query(L,R,0,m-1,1);            if(ans[L].first-l>res)            {                res=ans[L].first-l;            }            if(r-ans[R].last>res)            {                res=r-ans[R].last;            }            printf("%d\n",res);        }    }}





0 0