POJ-3261-Milk Patterns-二分+哈希

Posted ckxkexing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ-3261-Milk Patterns-二分+哈希相关的知识,希望对你有一定的参考价值。

Milk Patterns

题意:在一串数字中,求至少连续k次的最大子序列长度;

思路:二分加哈希;

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;

const int maxn = 20005;
const int p = 233;

int n,k,a[maxn+5]; 
unsigned long long hash1[maxn+5],F[maxn+5]={1};        //F数组用来保存p的次方,可能是pow()不稳定,慎用
unsigned long long re[maxn+5];

bool judge(int x)
{
    memset(re,0,sizeof(re));
    int tot = 0;
    for(int i=1;i<=n-x+1;i++)
    {
        int r = i+x-1;
        re[++tot] = (hash1[r]-hash1[i-1]*F[r-i+1]);
    }
    sort(re+1,re+1+tot);
    int cnt=1,mmax=1;
    unsigned long long last = re[1];
    for(int i=2;i<=tot;i++)
    {
        if(re[i]==last)
        {
            cnt++;
            if(cnt>mmax)mmax = cnt;
        }
        else 
        {
            cnt=1;
        }
        last = re[i]; 
    }
    return mmax >= k;
}

int main(){
    scanf("%d%d",&n,&k);
    hash1[0]=0;
    F[0] = 1;
    for(int i=1;i<=n;i++)
    {
        F[i] = F[i-1]*p;                
    }
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(i==1)hash1[i]=a[i];
        else 
            hash1[i] = hash1[i-1]*p +a[i];
    }
    int le = 1,ri = n;                    
    while(le+1<ri)
    {
        int mid = le + (ri-le)/2;
        if(judge(mid)) le = mid;
        else ri = mid;
    }
    printf("%d\n",le);
    return 0;
}

 

以上是关于POJ-3261-Milk Patterns-二分+哈希的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3261 Milk Patterns(后缀数组+二分答案)

poj 3261 Milk Patterns 后缀数组 + 二分

Poj3261 Milk Patterns(二分+后缀数组)

BZOJ1717&POJ3261Milk Patterns(后缀数组,二分)

poj 3261Milk Patterns 后缀数组

poj 3261Milk Patterns 后缀数组