1. 程式人生 > >詢問區間內出現次數最多的數出現的次數

詢問區間內出現次數最多的數出現的次數

POJ 3368 Frequent Values(RMQ)

題意:

        給出一個非降序排列的整數陣列a1,a2,...an,你的任務是對於一系列詢問(i, j),回答ai,ai+1,...aj中出現最多次數的值所出現的次數?

分析:劉汝佳:訓練指南P198

        1.      本題主要思想是把輸入序列分成一段段由相同值構成的序列,然後對於每個查詢[L,R]看他覆蓋了那些段,只要再這些連續的段範圍內找出現次數的最大值即可,即RMQ問題

        2.      由於a[n]是升序排列的,所以給a陣列遊程編碼為(v,num)其中v是a[i]的值,num是v這個相同的值出現的次數。用RMQ維護一個數組d[j]=num,表示從左到右出現的所有值中第j個出現的值連續出現了num次。

        3.      然後給每一個a[i]建立num[i], left[num[i]] , right[num[i]],分別表示:

        a[i]的值在所有出現的值中是在第num[i]個出現的(num[i]就是分析1中a[i]值的出現次數在RMQ中的編號j)

        與a[i]值相同的連續值最左邊的那個是位於left[num[i]]位置,最右邊的那個是位於right[num[i]]位置,並且。

        4.      對於一個查詢[L,R],首先求出L,和R分別屬於個num[],如果num[L]==num[R],那麼ans=R-L+1

GetMax

(num[L]+1,num[R]-1)次

        5.      最終結果就是

        MAX(right[num[L]]-L+1 ,R-left[num[R]]+1 ,GetMax(num[L]+1,num[R]-1))

<span style="font-size:18px;">#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN =200000+1000;
int dmax[MAXN][20];
int a[MAXN];
int left[MAXN],right[MAXN],num[MAXN];
int d[MAXN];//d[i]=8表第i個不同的值出現了8次
void initmax(int n,int d[])
{
    for(int i=1;i<=n;i++)
        dmax[i][0]=d[i];
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            dmax[i][j]=max( dmax[i][j-1],dmax[i+(1<<(j-1))][j-1] );
}
int getmax(int L,int R)
{
    int k=0;
    while(1<<(k+1)<=R-L+1)k++;
    return max(dmax[L][k],dmax[R+1-(1<<k)][k]);
}
int main()
{
    int n,q;
    while(scanf("%d",&n)==1&&n)
    {
        memset(d,0,sizeof(d));
        scanf("%d",&q);
        scanf("%d",&a[1]);
        int cnt=1;//表示當前出現了多少個不同的值
        left[cnt]=1;//第cnt段最左邊是位置1
        right[cnt]=1;//第cnt段最右邊是位置1
        num[1]=cnt;//第一個元素屬於第cnt段
        d[cnt]=1;//第cnt段目前有1個元素
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&a[i]);
            if(a[i]==a[i-1])
            {
                num[i]=cnt;
                right[cnt]=i;
                d[cnt]++;
            }
            else//出現新值
            {
                num[i]=++cnt;
                left[cnt]=i;
                right[cnt]=i;
                d[cnt]=1;
            }
        }
        initmax(n,d);//注意
        while(q--)
        {
            int L,R;
            scanf("%d%d",&L,&R);
            int num_L=num[L],num_R=num[R];
            if(num_L==num_R)
                printf("%d\n",R-L+1);
            else
            {
                int temp1=right[num[L]]-L+1;//a[L]出現的次數
                int temp2=R-left[num[R]]+1;//a[R]出現的次數
                int temp3=0;
                if(num_R-num_L>1)
                    temp3 = getmax(num_L+1,num_R-1);
                int ans = max(temp3,max(temp1,temp2));
                printf("%d\n",ans);
            }
        }
    }
    return 0;
}
</span>

相關推薦

詢問區間出現次數多的數出現次數

POJ 3368 Frequent Values(RMQ) 題意:         給出一個非降序排列的整數陣列a1,a2,...an,你的任務是對於一系列詢問(i, j),回答ai,ai+1,...aj中出現最多次數的值所出現的次數? 分析:劉汝佳:訓練指南P19

【Codeforces Round 365 (Div 2)D】【離線詢問 樹狀陣列 前驅思想】Mishka and Interesting sum 區間出現次數偶數的數的異或和

Little Mishka enjoys programming. Since her birthday has just passed, her friends decided to present her with array of non-negative integersa1, a2, ..., 

hdu 1806 Frequent values(給定一個非降序陣列,求任意區間出現次數多的數的次數)

1.題目解析可見《訓練指南》P198 2程式碼: #include<cstdio> #include<cstring> #include<cmath> #defin

POJ 3368 Frequent values(RMQ 求區間出現次數的數字的次數)

popu man most add scrip algo main for you 題目鏈接:http://poj.org/problem?id=3368 Description You are given a sequence of n int

POJ 3368 RMQ 找區間出現次數多的數

給出一個非降序排列的整數陣列a1,a2,...an,你的任務是對於一系列詢問(i, j),回答ai,ai+1,...aj中出現最多次數的值所出現的次數? <span style="font-size:18px;">#include<cstdio> #include<

尋找出現次數多的id

exti 出現 出現次數 util nbsp for pack 次數 題目 題目要求: 論壇中有一個id評論過於頻繁,其出現次數占到3/4,如今簡單編程尋找此id。 設計思想:

oj-ccf-csp-201312-1-出現次數多的數

str nbsp index name std print space {} include #include<cstdio> #include<algorithm> using namespace std; const int maxn

求一個字符串中連續出現次數多的子串

article 規律 生成 clu 一次 strong tor first sub 題目:求一個字符串中連續出現的次數最多的子串。 例如,字符串“abababc”,最多連續出現的為ab,連續出現三次。 思路: 例如字符串“abababc”,最多連續出現的為ab,連續出現

40.@返回字符串中出現次數多的那個字符和次數2

script 最大 spl 技術分享 char 獲取 code java log 1 <!DOCTYPE html> 2 <html> 3 <head lang="en"> 4 <meta charset="U

獲取字符串中出現次數多的字符

cti 次數 fun i++ ons ima ges inf += var stringUtil = {}; stringUtil.getMaxLengthCharacter = function(s){ var info = {}, getObj, getMa

js查找字符串中出現次數多的字符

獲取 bsp max for {} else 查找字符 hello 數量 js查找字符創中出現次數最多的字符及次數 var str = ‘Helloworldtomy‘; 1 function max(str){ 2 var json={}; 3 f

判斷一個字符串之中出現次數多的字符和它出現次數

div char for ole ++ 思路 i++ 最大值 sdh 判斷一個字符串之中出現次數最多的字符和它出現的次數!!! 思路:用一個空對象將字符串的各個字符和其出現的次數緩存起來,再通過比較次數的大小來判斷出最大值 (function(){ // 判斷一個

js常會問的問題:找出字符串中出現次數多的字符。

spl object 16px 說明 最大數 bsp 賦值 out 數列 一、循環obj let testStr = ‘asdasddsfdsfadsfdghdadsdfdgdasd‘; function getMax(str) {

UVALive-4670 AC自動機入門題 求出現次數多的子串

efi con sig http ati code fine mod long /** 鏈接:http://vjudge.net/problem/UVALive-4670 詳見lrj訓練指南P216 */ #include<bits/stdc++.h> usi

CCF CSP 201312-1 出現次數多的數

使用 col 空格 nbsp lan 題解 stdio.h con namespace CCF計算機職業資格認證考試題解系列文章為meelo原創,請務必以鏈接形式註明本文地址 CCF CSP 201312-1 出現次數最多的數 問題描述   給定n個正整數,找出

CCF 201312-1 出現次數多的數

turn rst clas size span adding stdin sub tor 試題編號: 201312-1 試題名稱: 出現次數最多的數 時間限制: 1.0s 內存限制: 256.0MB 問題描述: 問題描述   給定n個正整數,找出它

找出該字符串中出現次數多的那個字符

esp 表示 輸出 ive 出現次數 output post 字典 如果 /*時間限制 C/C++ 3s 其他 6s, 空間限制 C/C++ 32768k 其他 65535k 題目描述 給定一個長度不限的字符串,請找出該字符串中出現次數最多的那個字符,並打印出該字符

JavaScript數組中出現次數多的元素

javascrip OS val light clas else class ons 次數 var arr = [1,-1,2,4,5,5,6,7,5,8,6]; var maxVal = arr[0]; // 數組中的最大值 var minVal = arr[0]; /

獲取數組中出現次數多的數據及出現次數

family pan null spa ply 數據 PE urn on() Array.prototype.show=function(){ let _this=this; let arrs=[]; _this.forEa

判斷一個字符串中出現次數多的字符,統計這個次數

sdff BE 出現次數 div asd 遍歷 轉換成 arr str var str = ‘abaasdffggghhjjkkgfddsssss3444343‘; // 1.將字符串轉換成數組 var newArr = str.spl