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; }
skr