POJ 3368 Frequent values(RMQ 區間出現頻率最多數字次數)

來源:互聯網
上載者:User

題目連結:http://poj.org/problem?id=3368

題意:給定n個升序數組,然後輸入查詢區間,要求輸出這個區間內相同數位最大個數

解題思路:RMQ演算法

其實這個題目想到怎麼用RMQ演算法就基本上搞定了,如果想不到那麼就要費事一點了

其實這個題目痛點在於輸入的查詢區間不固定,有可能一串相連的的相同數位被查詢區間分割開了

那麼這樣就比較麻煩了,處理起來也比較費事,可是稍微想一下,可以把一個查詢分開成

兩個部分來查詢,一個是前面部分被分割的部分,一個是後面的部分

在用RMQ初始化之間我們先做了一個預先處理,就是這樣:

      for(i=2;i<=n;i++)        {            if(rec[i]==rec[i-1])            tim[i].num=tim[i-1].num+1;            else            {                for(k=i-tim[i-1].num;k<i;k++)                tim[k].fast=i-1;                tim[i].num=1;            }        }

也就是當前字元前面出現多少次,注意是前面出現多少次,計算出來,然後再回去把前面的出現字元相同的位置記錄出最後一個相同字元出現的位置的標號

接下來就是對tim數組的num進行RMP初始化,完成之後查詢

if(b<=tim[a].fast)            printf("%d\n",query(a,b)-tim[a].num+1);            else            printf("%d\n",MAX(query(a,tim[a].fast)-tim[a].num+1,query(tim[a].fast+1,b)));

查詢是上面一段代碼,如果右邊的(a,b)這個區間一直都是一個數字,那麼直接查詢區間(a,b)然後減去在到a的時候這個數字已經出現的次數

完了之後就是分開兩個區間查詢,一個是左邊區間到和一直數字相等的位置,然後就是後面的到b,兩者取較大的就OK 了!

#include <stdio.h>#include <string.h>
#include <iostream>#include <cmath>#include <algorithm>using namespace std;#define maxn 210000#define MAX(a,b) (a>b?a:b)int rec[maxn];//int tim[maxn];struct node{    int num;    int fast;}tim[maxn];int map[maxn][20];int n,m;int init_rmq(int len){    int i,j,k;    for(i=1;i<=len;i++)    map[i][0]=tim[i].num;    for(j=1;j<20;j++)    for(i=1;i<=len && ((1<<(j-1))+i)<=len;i++)    {       map[i][j]=MAX(map[i][j-1],map[i+(1<<(j-1))][j-1]);    }    return 0;}int query(int L,int R){    int k=int(log(double(R-L+1))/log(2.0));    return MAX(map[L][k],map[R-(1<<k)+1][k]);}int main(){    int i,j,k;    int a,b;    while(scanf("%d",&n),n)    {        scanf("%d",&m);        for(i=1;i<=n;i++)        scanf("%d",&rec[i]);        k=1;        tim[1].num=1;        for(i=2;i<=n;i++)        {            if(rec[i]==rec[i-1])            tim[i].num=tim[i-1].num+1;            else            {                for(k=i-tim[i-1].num;k<i;k++)                tim[k].fast=i-1;                tim[i].num=1;            }        }         for(k=i-tim[i-1].num;k<i;k++)            tim[k].fast=i-1;        init_rmq(n);        for(i=0;i<m;i++)        {            scanf("%d%d",&a,&b);            if(b<=tim[a].fast)            printf("%d\n",query(a,b)-tim[a].num+1);            else            printf("%d\n",MAX(query(a,tim[a].fast)-tim[a].num+1,query(tim[a].fast+1,b)));        }        //for(i=0;i<=n;i++)        //printf("%d %d\n",tim[i].num,tim[i].fast);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.