zoukankan      html  css  js  c++  java
  • POJ 3368 Frequent values (ST表)

    题面

    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.

    题解

    给你一个序列,然后有m次的查询,每次查询给你左右端点,问你区间内的最长连续序列是多长(元素全部相同)。区间询问,考虑st表,那么我们统计每个序列是以它为值的答案序列的第几项。然后因为是有序序列,所以查询的时候先二分出大于他的哪个元素下标,然后对前一个与右边界比较,如果大于那么就询问的区间长度就是答案吗,如果不是的话,那么我们就比较二分到的长度,和后半部分的答案,去取max,后半部分的答案可以用st表来维护(维护num值)。

    代码实现

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int maxn=1e5+10;
    const int inf=0x3f3f3f3f;
    typedef pair<int,int> PII;
    void check_min (int &a,int b) {a=min (a,b);}
    void check_max (int &a,int b) {a=max (a,b);}
    int n,m;
    int data[maxn],num[maxn],dp[20][maxn];
    
    inline void RMQ () {
      for (int i=1;i<=n;i++) dp[0][i]=num[i];
      int k=__lg (n+1);
      for (int j=1;j<=k;j++) 
       for (int i=1;i+(1<<j-1)<=n;i++) {
        dp[j][i]=max (dp[j-1][i],dp[j-1][i+(1<<(j-1))]);
       }
      return ;
    }
    
    int ask (int x,int y) {
      int k=__lg (y-x+1);
      return max (dp[k][x],dp[k][y-(1<<k)+1]);
    }
    
    int main () {
      while (scanf ("%d",&n)) {
        memset (num,0,sizeof (num));
        // for (int i=1;i<=n;i++) printf ("%d ",num[i]);
        // printf ("
    ");
        if (n==0) break;
        scanf ("%d",&m);
        for (int i=1;i<=n;i++) scanf ("%d",&data[i]);
        for (int i=1;i<=n;i++) {
          if (i==1||data[i]!=data[i-1]) num[i]=1;
          else num[i]=num[i-1]+1;
        }
        RMQ ();
        // for (int i=1;i<=n;i++) printf ("%d ",&num[i]);
        // printf ("
    ");
        while (m--) {
          int a,b,ans=1;
          scanf ("%d%d",&a,&b);
          int pos=upper_bound (data+1,data+1+n,data[a])-data;
          if (pos>b) ans=b-a+1;
          else {
            ans=pos-a;
            check_max (ans,ask (pos,b));
          }
          printf ("%d
    ",ans);
        }
      }
      return 0;
    }
    
  • 相关阅读:
    7 文件操作
    初识字典1
    软件工程学习进度
    AAAA
    软件工程期末总结
    【操作系统】实验四 主存空间的分配和回收 截止提交时间:2016.6.17
    约教网站开发(一)
    操作系统实验三
    .Scrum团队成立
    数学精灵改进
  • 原文地址:https://www.cnblogs.com/hhlya/p/13995763.html
Copyright © 2011-2022 走看看