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

    【题意】给定长度为n和m的两个字符串S和T,要求在字符串S中取出若干段拼成T(可重复取),求最小段数,n,m<=50000。

    【算法】后缀自动机 || 后缀数组

    【题解】对串S建SAM,然后在上面尽可能地匹配T,匹配几次得到T就是答案。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cctype>
    using namespace std;
    const int maxn=100010;
    struct tree{int len,fa,t[30];}t[maxn*2];
    int tot,last,n,m,b[maxn];
    void insert(int c){
        int np=++tot;
        t[np].len=t[last].len+1;
        int x=last;
        while(x&&!t[x].t[c])t[x].t[c]=np,x=t[x].fa;
        last=np;
        if(!x)t[np].fa=1;else{
            int y=t[x].t[c];
            if(t[y].len==t[x].len+1)t[np].fa=y;else{
                int nq=++tot;
                t[nq]=t[y];
                t[nq].len=t[x].len+1;
                t[nq].fa=t[y].fa;t[y].fa=t[np].fa=nq;
                while(x&&t[x].t[c]==y)t[x].t[c]=nq,x=t[x].fa;
            }
        }
    }
    int main(){
        scanf("%d%d",&n,&m);
        tot=last=1;
        for(int i=1;i<=n;i++){
            char c=getchar();
            while(c<'A'||c>'Z')c=getchar();
            insert(c-'A');
        }
        for(int i=1;i<=m;i++){
            char c=getchar();
            while(c<'A'||c>'Z')c=getchar();
            b[i]=c-'A';
        }
        int len=1,ans=0;
        while(len<=m){
            int now=1;
            while(len<=m&&t[now].t[b[len]])now=t[now].t[b[len++]];
            ans++;
        }
        printf("%d",ans);
        return 0;
    }
    View Code
  • 相关阅读:
    Eclipse中项目去除Js验证
    Web安全扫描工具
    Oracle-定时任务
    About_Return
    About_php_封装函数
    About_PHP_函数
    About_PHP_验证码的生成
    About_PHP_文件的上传
    About_MySQL Select--来自copy_03
    About_AJAX_03
  • 原文地址:https://www.cnblogs.com/onioncyc/p/8118348.html
Copyright © 2011-2022 走看看