POJ 3368: Frequent values

来源:互联网 发布:成都四平软件怎么样 编辑:程序博客网 时间:2024/05/04 08:36

题意:

给出一个单调非减序列,

询问a[i]~a[j]区间内出现最多的元素出现了多少次


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


算法:

RMQ的典型应用,

以前都是用线段树实现的RMQ,

今天特意学习了一下O(nlogn+q)的RMQ算法


代码如下:

//其实我是来存模板的难道我会到处乱说?#include<cstdio>#include<iostream>#include<sstream>#include<cstdlib>#include<cstring>#include<string>#include<climits>#include<cmath>#include<algorithm>#include<queue>#include<vector>#include<stack>#include<set>#include<map>#define INF 0x3f3f3f3f#define eps 1e-8using namespace std;const int MAXN=110000;const int MAXM=18;int rmq[MAXN][MAXM],a[MAXN],pre[MAXN],nxt[MAXN];vector<int>hash;int main() {    int n;    while(scanf("%d",&n)==1&&n) {        int q;        scanf("%d",&q);        hash.clear();        memset(rmq,0,sizeof(rmq));        for(int i=0; i<n; i++) {            scanf("%d",&a[i]);            hash.push_back(a[i]);        }        hash.erase(unique(hash.begin(),hash.end()),hash.end());        for(int i=0; i<n; i++) {            a[i]=lower_bound(hash.begin(),hash.end(),a[i])-hash.begin();            rmq[a[i]][0]++;        }        pre[0]=-1;        for(int i=0; i<n; i++) {            if(a[i]==a[i-1]) {                pre[i]=pre[i-1];            } else {                pre[i]=i-1;            }        }        nxt[n-1]=n-1;        for(int i=n-2; i>=0; i--) {            if(a[i]==a[i+1]) {                nxt[i]=nxt[i+1];            } else {                nxt[i]=i+1;            }        }        int cot=hash.size();        for(int j=1; j<MAXM; j++) {            for(int i=0; (i+(1<<j))<=cot; i++) {                rmq[i][j]=max(rmq[i][j-1],rmq[i+(1<<(j-1))][j-1]);            }        }        while(q--) {            int x,y;            scanf("%d%d",&x,&y);            x--;            y--;            if(a[x]==a[y]) {                printf("%d\n",y-x+1);                continue;            }            int tmp=nxt[x]-x;            x=a[x]+1;            tmp=max(tmp,y-pre[y]);            y=a[y]-1;            if(x>y) {                printf("%d\n",tmp);                continue;            }            int k=(int)log2(y-x+1);            tmp=max(tmp,max(rmq[x][k],rmq[y-(1<<k)+1][k]));            printf("%d\n",tmp);        }    }    return 0;}


原创粉丝点击