码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 3368 Frequent values (ST表)

时间:2020-11-21 12:28:36      阅读:7      评论:0      收藏:0      [点我收藏+]

标签:长度   term   using   return   amp   long   连续序列   cto   ret   

题面

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 ("\n");
    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 ("\n");
    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\n",ans);
    }
  }
  return 0;
}

POJ 3368 Frequent values (ST表)

标签:长度   term   using   return   amp   long   连续序列   cto   ret   

原文地址:https://www.cnblogs.com/hhlya/p/13995763.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!