1. 程式人生 > >POJ-3261-Milk Patterns-二分+哈希

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

scan for post scanf can targe last spa .net

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-二分+哈希