zoukankan      html  css  js  c++  java
  • 1030: [JSOI2007]文本生成器 ac自动机+dp

    https://www.lydsy.com/JudgeOnline/problem.php?id=1030

    求长度为m不包含n个子串的种数,

    跑完ac自动机之后没办法跑矩阵快速幂,因为状态数比较大(6000),所以dp转移,dp[i][j]表示前i个跑到j状态的不包含子串的情况数

    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    //#define mod 1000000007
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    
    using namespace std;
    
    const double g=10.0,eps=1e-12;
    const int N=6000+10,maxn=200000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
    
    ll n,m,dp[110][N];
    ll quick(ll a,ll b,ll c)
    {
        ll ans=1;
        while(b)
        {
            if(b&1)ans=ans*a%c;
            a=a*a%c;
            b>>=1;
        }
        return ans;
    }
    char s[N];
    struct ACM{
        int root,tot;
        int Next[N][30],fail[N],End[N];
        int newnode()
        {
            memset(Next[tot],-1,sizeof Next[tot]);
            End[tot]=0;
            return tot++;
        }
        ACM()
        {
            tot=0;
            root=newnode();
        }
        void ins()
        {
            int now=root,len=strlen(s);
            for(int i=0;i<len;i++)
            {
                if(Next[now][s[i]-'A']==-1)
                    Next[now][s[i]-'A']=newnode();
                now=Next[now][s[i]-'A'];
            }
            End[now]=1;
        }
        void build()
        {
            queue<int>q;
            fail[root]=root;
            for(int i=0;i<26;i++)
            {
                if(Next[root][i]==-1)Next[root][i]=root;
                else
                {
                    fail[Next[root][i]]=root;
                    q.push(Next[root][i]);
                }
            }
            while(!q.empty())
            {
                int now=q.front();
                q.pop();
                if(End[fail[now]])End[now]=1;
                for(int i=0;i<26;i++)
                {
                    if(Next[now][i]==-1)Next[now][i]=Next[fail[now]][i];
                    else
                    {
                        fail[Next[now][i]]=Next[fail[now]][i];
                        q.push(Next[now][i]);
                    }
                }
            }
        }
        void solve()
        {
            dp[0][0]=1;
            for(int i=1;i<=m;i++)
            {
                for(int j=0;j<tot;j++)
                {
                    if(!End[j]&&dp[i-1][j])
                    {
                        for(int k=0;k<26;k++)
                        {
                            int now=j;
                            while(Next[now][k]==-1)now=fail[now];
                            dp[i][Next[now][k]]=(dp[i][Next[now][k]]+dp[i-1][j])%10007;
                        }
                    }
                }
            }
            ll ans=quick(26,m,10007);
            for(int i=0;i<tot;i++)
                if(!End[i])
                    ans=((ans-dp[m][i])%10007+10007)%10007;
            printf("%lld
    ",ans);
        }
    }ac;
    int main()
    {
        scanf("%lld%lld",&n,&m);
        for(int i=0;i<n;i++)
        {
            scanf("%s",s);
            ac.ins();
        }
        ac.build();
        ac.solve();
        return 0;
    }
    /***********************
    
    ***********************/
    View Code
  • 相关阅读:
    交叉熵的数学原理及应用——pytorch中的CrossEntropyLoss()函数
    pytorch中如何使用DataLoader对数据集进行批处理
    Pytorch中的自动求导函数backward()所需参数含义
    Pytorch中的torch.cat()函数
    Pytorch中的squeeze()和unsqueeze()函数
    UBUNTU18.04安装网易云音乐并直接图标启动
    UBUNTU18.4环境下使用更好用的搜索引擎(无奈,只能起这样的标题)
    Ubuntu 18.04换国内源 中科大源 阿里源 163源 清华源
    共享栈
    C++(十七) — 宏代码、内联函数
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8964376.html
Copyright © 2011-2022 走看看