1. 程式人生 > >POJ 3368 RMQ--ST

POJ 3368 RMQ--ST

e of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (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 n integers 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 10
2 3
1 10
5 10
0

Sample Output

1
4
3

先說一下題意 給出n個不減的數,詢問Q次,求這n個數中連續的相等的數的最大數量

思路:將全陣列轉化成兩個陣列xu[ ]代表著數字的順序-1 -1 1 1 1 1 3 10 10 10 就是

                                                                                      1   2 1 2 3 4 1 1 2 3

wei[ ]就是每一串相同字元的尾部index                          2 2 6 6 6 6 7 10 10 10

還有一個 求區間 最大值的 RMQ  

ans    如果要查詢的wei[l]和wei[r] 相等的話直接就是l-r+1

         其他情況  左邊部分的l-r+1右邊部分的RMQ求最大值

#include<iostream>
#include<stdio.h>
using namespace std;
int num[100009];
int xu[100009];
int wei[100009];
int dp[100009][30];
int n,q;
void ST(int n)
{
    for (int i = 1; i <= n; i++)
        dp[i][0] = xu[i];
    for (int j = 1; (1 << j) <= n; j++)
    {
        for (int i = 1; i + (1 << j) - 1 <= n; i++)
        {
            dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
        }
    }
}
int RMQ(int l, int r)
{
    int k = 0;
    while ((1 << (k + 1)) <= r - l + 1) k++;
    return max(dp[l][k], dp[r - (1 << k) + 1][k]);
}
int main()
{
    while(cin>>n)
    {
        if(n==0)
            break;
        cin>>q;
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&num[i]);
        }
        xu[1]=1;
        for(int i=2; i<=n; i++)
        {
            if(num[i]==num[i-1])
                xu[i]=xu[i-1]+1;
            else xu[i]=1;
        }
        wei[n]=n;
        for(int i=n-1; i>0; i--)
        {
            if(num[i]==num[i+1])
                wei[i]=wei[i+1];
            else
                wei[i]=i;
        }
            ST(n);
        for(int i=0; i<q; i++)
         {
              int l,r;
              scanf("%d%d",&l,&r);
              if(wei[l]==wei[r])
                printf("%d\n",xu[r]-xu[l]+1);
              else
                printf("%d\n",max(wei[l]-l+1,RMQ(wei[l]+1,r)));
         }
    }
    return 0;
}

相關推薦

POJ 3368 RMQ--ST

e of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and j (1 ≤ i ≤

POJ 3368 RMQ--ST

e of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you are given several queries consisting of indices i and

poj 3368 - RMQ

題目連結:https://vjudge.net/problem/POJ-3368   解題思路: 題目給出不降序列, 令f[i] = v[i]==v[i-1]? f[i]+1 : 1; 查詢區間f[i]的最大值可以RMQ,都是要對l進行剪下,使得v[l]的值是第一次

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

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

POJ 3368 Frequent values 【STRMQ 維護區間頻率最大值】

傳送門:http://poj.org/problem?id=3368 Frequent values Time Limit: 2000MS   Memory Limit: 65536K

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】Frequent values(RMQ

Description You are given a sequence of n integers a1 , a2 , ... , an in non-decreasing order. In addition to that, you a

RMQ - ST算法

ems 一個 sca scanf nbsp target iostream light ret 題目鏈接 --------------------------------------------------------------------------------- pr

Ural 1297 Palindrome(Manacher或者後綴數組+RMQ-ST

奇數 receive scribe exce rmq channel ignore uri turn 1297. Palindrome Time limit: 1.0 second Memory limit: 64 MB The “U.

HihoCoder 1068 RMQ-ST算法+BIT

就是 數字 str ron 區間 公共祖先 inf 範圍 偶數 以前都是用的BIT或者線段樹(前者多一些)。 對於ST(Sparse Table),在求倍增or公共祖先時見過,說明還有其他用處,所以還是學習一下。 首先是預處理,用動態規劃(DP)解決。 設A[i]是

NYOJ 119 士兵殺敵(三) RMQ ST

turn lin clu 1.0 net mark pre ref void NYOJ 119 士兵殺敵(三) RMQ ST 題目鏈接:http://acm.nyist.net/JudgeOnline/problem.php?pid=119 思路: ST在線 預處理O(n

1068 : RMQ-ST算法

隨機數 turn 0ms 區間 意義 hihocode coder 宇宙 div #1068 : RMQ-ST算法 時間限制:10000ms 單點時限:1000ms 內存限制:256MB 描述 小Hi和小Ho在美國旅行了相當長的一段時間

【hiho】16 RMQ-ST算法【RMQ-ST算法】

長度 com lin line 最小 make long long turn long 傳送門:RMQ-ST算法 RMQ(Range Minimum/Maximum Query)區間範圍最值查詢問題 題意 求指定區間值最小的元素 思路 其實就是二分法的思路,統計所有長度為2

RMQ-ST

                        

hihocoder1068 RMQ-ST演算法

思路: 這是ST表模板。遇到一道indeed筆試題需要用這個演算法,順便學習一下。那道題是說給定一個一維陣列和一些查詢[Li, Ri],要求計算[Li, Ri]區間內子段和的絕對值的最大值。解法是使用ST表計算所求區間內最大字首和 - 最小字首和即可。 實現: 1 #include <bi

HDU3183-RMQ(ST表)

#include<bits/stdc++.h> using namespace std; string s; char Ans[10000]; int PosDP[10005][1005]; int RQ(int i,int j) { return s[i] <= s[j] ?

Frequent values POJ - 3368(線段樹,區間合併)

Frequent values POJ - 3368 題目連結 題意:一個非遞減序列,隨機詢問區間[l, r]中出現次數最多的數的出現次數; 思路:多次詢問,首先就要想一下線段樹;由題意可知數列中的數是連續的,既然是連續的就有合併的希望!!!那麼就來一發線段樹吧(RMQ也可以做

最近公共祖先-三(RMQ-ST

描述 上上回說到,小Hi和小Ho使用了Tarjan演算法來優化了他們的“最近公共祖先”網站,但是很快這樣一個離線演算法就出現了問題:如果只有一個人提出了詢問,那麼小Hi和小Ho很難決定到底是針對這個詢問就直接進行計算還是等待一定數量的詢問一起計算。畢竟無論是一個詢問還是很多

與眾不同 RMQ——ST表的運用

inline void ST(int n){ int maxlog=log2(n); for(int j=1;j<=maxlog;++j) for(int i=1;i+(1<<j-1)-1<=n;++i) mx[i][j]=max(mx[

【2018黑龍江省賽】UPC-7218 A Sequence Game(莫隊&離散化&RMQ ST表)

題目描述 One day, WNJXYK found a very hard problem on an Online Judge. This problem is so hard that he had been thinking about the solu