poj3261ミルクパターン(バイナリーハッシュ+)

ファーマージョンは彼の牛によって与えられたミルクの品質は日々変化していることに気づきました。さらに調査では、彼は彼が1日から次へと牛乳の品質を予測することはできないものの、いくつかの規則的なパターンが毎日牛乳の品質であることを発見しました。

厳格な調査を行うために、彼は各ミルクサンプルは0〜1,000,000までの整数として記録されることにより、複雑な分類方式を発明した、とN(1≤N≤2万)日間にわたり、単一の牛からのデータを記録しています。彼は同じ少なくともK(2≤K≤N)回繰り返さ試料の最長のパターンを見つけることを望みます。例えば、1 2 3 2 3 2 3 1回繰り返す3 2 3 2、 - これは、重複するパターンを含んでもよいです。

ヘルプファーマージョン・サンプルのシーケンスで最長の繰り返しサブシーケンスを見つけることもできます。少なくとも1つのサブシーケンスは、少なくともK回で繰り返されることが保証されています。

INPUT
。1行目:二つの整数スペースで区切ら:NとK
線を2 ... N + 1:Nの整数、1行に1つずつ、牛乳日Iの品質I番目の行に表示されます。
出力
ライン1:一つの整数、長さこれはAT K回の最長パターン最小発生
サンプル入力
2. 8
。1
2
3
2
3
2
。3
。1
出力例
4
長さNの文字列に、kのすべての出現を検索サブストリングストリングは、最長FOUNDの長さよりも大きいですその、および出力長。
思考:(排他的論理和してもよいが、排他的論理和値を維持するために、プレフィックスとプレフィックスと類似している場合の前に一度も遭遇し、)接頭辞と同様のアイデアがあり、1から使用されるハッシュストリングのIに示し、[I]ハッシュ値に対応し、各部分10は、我々はO(1)は、対応するハッシュ値を取得することができ、特定のサブストリングのために、次に、小数番号に見られます。我々は唯一の逆長さlenを列挙するために必要な、サブの現在の長さの(、ハッシュ値を、対応する発生回数である)の回数を見ては、これ以上kよりもあります表示されませんし、直接ブレークへの答えがあり、その後、トン。
実際には、長さの列挙があり、特定の長さlの列挙は、すべての少ないLよりも、可能であれば可能であり、我々は唯一のも場合よりも大きいの長さlをチェックする必要が単調です我々は条件を満たさなければなりません。だから、半分答えがなければならない
この質問カードマップは、私はTTを渡すことができませんでした出現マップレコード番号を使用した場合、まだわかりません

//#include<bits/stdc++.h>
#include<map>
#include <algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#define mod (1000000007)
#define middle (l+r)>>1
#define SIZE 1000000+5
#define lowbit(x) (x&(-x))
#define lson (rt<<1)
#define rson (rt<<1|1)
typedef long long ll;
typedef long double ld;
const int inf_max = 0x3f3f3f;
const ll Linf = 9e18;
const int maxn = 2e4+10;
const long double E = 2.7182818;
const double eps=0.0001;
using namespace std;
inline int read()
{
    int f=1,res=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
    while(ch>='0'&&ch<='9') { res=res*10+ch-'0' ; ch=getchar(); }
    return f*res;
}
int n,k,ans;
ll a[maxn],Hash[maxn],pval[maxn],cur[maxn];
const ll base = 10;
bool check(int i) {
    for(int l = 1;l <= n - i + 1; ++l) {
        int r = l + i - 1;
        cur[l] = (Hash[r] - (Hash[l - 1] * pval[r + 1 - l] % mod) % mod + mod) % mod;  
    }
    // printf("%d %lld,%lld\n",n - i + 1,cur[1],cur[2]);
    sort(cur + 1,cur + n - i + 2);
    int maxv = 1,cnt = 1;
    ll num = cur[1];
    for(int j = 2;j <= n - i + 1; ++j) {  //统计相同的数出现的次数,取满足条件的最大值
        if(cur[j] != cur[j - 1]) {
            num = cur[j];
            maxv = max(maxv,cnt);
            cnt = 1;
        }
        else ++cnt;
    }
    //printf("cnt=%d\n",cnt);
    maxv = max(maxv,cnt);
    return (maxv >= k);
}
int main()
{
    while(~scanf("%d%d",&n,&k)) {
        ans = 0;
        memset(Hash,0,sizeof(Hash));
        for(int i = 1;i <= n; ++i) {
            scanf("%lld",&a[i]);
        }
        pval[0] = 1;
        for(int i = 1;i <= n; ++i) {
            pval[i] = pval[i - 1] * base % mod;  //预处理一下后面要用的值
            Hash [i] = (Hash[i - 1] * base % mod + a[i]) % mod;
        }
        int L = 1,R = n;
        while(L <= R) {
            int mid = (L + R) >> 1;
            //printf("mid=%d %d\n",mid,check(mid));
            if(check(mid)) {
                ans = mid;
                L = mid + 1;
            }else R = mid - 1;
        }
        printf("%d\n",ans);
    }
    return 0;
}
公開された33元の記事 ウォン称賛14 ビュー408

おすすめ

転載: blog.csdn.net/qq_44077455/article/details/104031357