zoukankan      html  css  js  c++  java
  • [Usaco2006 Dec] Milk Patterns 产奶的模式

    Description

    给定一个数字串 (S),求出现了 (k) 次的子串的最大长度。

    Solution

    考虑基于 std::map 的 SAM

    出现 (k) 次的条件就是要求 (endpos) 集合的大小 (ge k)

    于是我们在满足这个条件的所有节点的 (len) 中取最大即可

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 200005;
    struct SAM {
        int len[N], fa[N], ind, last;
        map<int,int> ch[N];
        int t[N], a[N], cnt[N], f[N];
        SAM() { ind = last = 1; }
        inline void extend(int id) {
            int cur = (++ ind), p;
            len[cur] = len[last] + 1;
            cnt[cur] = 1;
            for (p = last; p && !ch[p][id]; p = fa[p]) ch[p][id] = cur;
            if (!p) fa[cur] = 1;
            else {
                int q = ch[p][id];
                if (len[q] == len[p] + 1) fa[cur] = q;
                else {
                    int tmp = (++ ind);
                    len[tmp] = len[p] + 1;
                    ch[tmp] = ch[q];
                    fa[tmp] = fa[q];
                    for (; p && ch[p][id] == q; p = fa[p]) ch[p][id] = tmp;
                    fa[cur] = fa[q] = tmp;
                }
            }
            last = cur;
        }
        void calcEndpos() {
            memset(t, 0, sizeof t);
            for(int i=1; i<=ind; i++) t[len[i]]++;
            for(int i=1; i<=ind; i++) t[i]+=t[i-1];
            for(int i=1; i<=ind; i++) a[t[len[i]]--]=i;
            for(int i=ind; i>=1; --i) cnt[fa[a[i]]]+=cnt[a[i]];
            cnt[1] = 0;
        }
        int solve(int k)
        {
            int ans=0;
            for(int i=1;i<=ind;i++)
            {
                if(cnt[i]>=k) ans=max(ans,len[i]);
            }
            return ans;
        }
    } sam;
    
    int main() {
        ios::sync_with_stdio(false);
        int n,k,t;
        cin>>n>>k;
        for(int i=1;i<=n;i++)
        {
            cin>>t;
            sam.extend(t);
        }
        sam.calcEndpos();
        cout<<sam.solve(k)<<endl;
    }
    
    
    
  • 相关阅读:
    【洛谷P4887】【模板】莫队二次离线(第十四分块(前体))
    查询数据库表大小
    java程序使用ssl证书连接mysql
    win32- 函数运行速度测试
    回调函数是嘛东西
    win32-读取控制台中所有的字符串
    关于 websocket 的一些学习
    idea下载地址
    ida 重新定义
    P1650 田忌赛马(贪心)
  • 原文地址:https://www.cnblogs.com/mollnn/p/13282944.html
Copyright © 2011-2022 走看看