zoukankan      html  css  js  c++  java
  • BZOJ 2099 [Usaco2010 Dec]Letter 恐吓信

    BZOJ_2099

        一个可行的贪心思路就是,每次都让这刀切出的串越长越好,然后下一次再从上一刀末尾后面那个字符开始,继续这样贪心地去切。

        这样就要反复查询,从某个位置开始,最长能有多少个连续的字符满足是文章中的一个子串,这一点可以将文章建立后缀自动机后来查找,整体查找的复杂度是O(N)的。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 50010
    struct SufAuto
    {
        int pre, next[26], len;
        void init()
        {
            memset(next, 0, sizeof(next));
            pre = -1, len = 0;
        }
    }sa[2 * MAXD];
    namespace SA
    {
        int node, tail;
        void init()
        {
            node = tail = 0;
            sa[0].init();
        }
        void insert(int k, int len)
        {
            int p = tail, np = ++ node;
            sa[np].init();
            sa[np].len = len;
            for(; p != -1 && !sa[p].next[k]; p = sa[p].pre) sa[p].next[k] = np;
            tail = np;
            if(p == -1) sa[np].pre = 0;
            else
            {
                if(sa[sa[p].next[k]].len == sa[p].len + 1) sa[np].pre = sa[p].next[k];
                else
                {
                    int q = sa[p].next[k], r = ++ node;
                    sa[r] = sa[q], sa[r].len = sa[p].len + 1;
                    sa[q].pre = sa[np].pre = r;
                    for(; p != -1 && sa[p].next[k] == q; p = sa[p].pre) sa[p].next[k] = r;
                }
            }
        }
    }
    int N, M;
    char a[MAXD], b[MAXD], str[110];
    void init()
    {
        int cnt = 0;
        while(cnt < N)
        {
            scanf("%s", str);
            int n = strlen(str);
            strcpy(a + cnt, str);
            cnt += n;
        }
        cnt = 0;
        while(cnt < M)
        {
            scanf("%s", str);
            int n = strlen(str);
            strcpy(b + cnt, str);
            cnt += n;
        }
        SA::init();
        for(int i = 0; i < N; i ++) SA::insert(a[i] - 'A', i + 1);
    }
    void solve()
    {
        int cnt = 0, cur = 0;
        while(cur < M)
        {
            for(int i = 0; b[cur] && sa[i].next[b[cur] - 'A']; i = sa[i].next[b[cur ++] - 'A']);
            ++ cnt;
        }
        printf("%d\n", cnt);
    }
    int main()
    {
        while(scanf("%d%d", &N, &M) == 2)
        {
            init();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    滚动 冻结 div demo
    JavaScript去除字符串两边空格trim
    window.showModalDialog以及window.open用法简介
    转: 分享我创业4年失败的经历
    [转]JavaScript break跳出多重循环
    showModalDialog 传值及刷新
    防止文字撑开表格,强制表格大小
    带记忆功能的表单
    checkbox 全选
    asp教程:关于jquery跨域彻底的解决方法
  • 原文地址:https://www.cnblogs.com/staginner/p/2719254.html
Copyright © 2011-2022 走看看