zoukankan      html  css  js  c++  java
  • POJ3368(RMQ)

                                                         Frequent values

    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 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

    解题思路:

    可以求出相同数的的个数(可以离散),但是如果所求区间切断了连续区间怎么办,分成三段,左边一段,右边一段,中间的就可以用线段树(不用更新,RMQ要简单一点)或者RMQ算最大值。

    具体代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #define N 100005
     5 using namespace std;
     6 int a[N],lo[N],pos[N];
     7 int n,m,x,y;
     8 struct ii
     9 {
    10     int sta,end;
    11     int num;
    12 }aa[N];
    13 int f[N][20];
    14 int main()
    15 {
    16     freopen("poj3246.in","r",stdin);
    17     freopen("poj3246.out","w",stdout);
    18     //RQM 初始化,把log2(i),先打表出来 
    19     //f[][]是以连续区间个数,不是n个 
    20     while((scanf("%d%d",&n,&m))==2)
    21     {
    22         int i=1,q=2,p=0;
    23     lo[i]=0;
    24     while(i<=n)
    25     {
    26         i++;
    27         if(i==q)
    28         {
    29             q*=2;
    30             p++;
    31         }
    32         lo[i]=p;
    33     }
    34     int pre=N;
    35     int k=0;
    36     for(int i=1;i<=n;i++)//aa记录连续区间的起点中点个数 
    37     {
    38         scanf("%d",&a[i]);
    39         if(a[i]!=pre)
    40         {
    41             k++;
    42             aa[k].sta=i;
    43             aa[k].end=i;//记录k的始末 
    44             pre=a[i];
    45         }
    46         else aa[k].end=i;
    47         pos[i]=k;//记录下标所对应的k 
    48     }
    49     for(int i=1;i<=k;i++)
    50     aa[i].num=aa[i].end-aa[i].sta+1;
    51     for(int i=1;i<=k;i++)
    52     f[i][0]=aa[i].num; 
    53     for(int j=1;j<=lo[n]+1;j++)
    54     for(int i=1;i<=k;i++)
    55     if(i+(1<<j)-1<=k)
    56     f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]);//分成等量两段长度为1<<j-1 
    57     for(int i=1;i<=m;i++)
    58     {
    59         scanf("%d%d",&x,&y);
    60         if(pos[x]==pos[y])cout<<y-x+1<<endl;
    61         else 
    62         {
    63             int a1=aa[pos[x]].end;
    64             int b1=aa[pos[y]].sta;
    65             int n1=a1-x+1;
    66             int n2=0;
    67             int n3=y-b1+1;
    68             int k1=pos[x],k2=pos[y];
    69             int p=lo[k2-k1+1-2];//都是连续区间个数 
    70             if(k2-k1-1==0)cout<<max(n1,n3)<<endl;
    71             else
    72             {
    73                 n2=max(f[k1+1][p],f[k2-1-(1<<p)+1][p]);
    74                 cout<<max(max(n1,n2),n3)<<endl;
    75             }
    76         } 
    77     } 
    78     }
    79     return 0;
    80 }

     总结:

    1.RMQ求最值的用法

    2,RMQ(线段树)的应用,不完全用,先分成三部分,中间一部分用RMQ

    3,RMQ:f[i][j]初始化f[i][0]=a[i];

    f[i][j]=max(f[i][j-1],f[i+(1<<j-1)][j-1]),递推,for(j:1-log2(n))for(i:1-n)[j是外层循环,i是内层,先推两个的最大值,然后再是四个,八个]

    4.看清题目,是多组数据

  • 相关阅读:
    软件工程团队作业2.1——《业务流程模型》
    软件工程团队作业1——《调研提纲》
    2020软件工程第四次作业
    作业四(一)
    17074230 团队项目选题报告
    计算与软件工程 作业5
    计算与软件工程 作业4
    17074230 第三次作业
    17074230 第二次作业
    17074230 赵雅雅 第一次作业
  • 原文地址:https://www.cnblogs.com/abcfrey/p/5668346.html
Copyright © 2011-2022 走看看