• hdu2243 ac自动机+矩阵快速幂


    和上一题有点相似,但是这题是求包含的,并且还要求和

    可以求所有情况-不包含的情况,所有情况可用矩阵快速幂求得

    还有一点就是如果题目说答案余2^64,直接开unsigned long long就行了,会自动取膜的

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define C 0.5772156649
    #define pi acos(-1.0)
    #define ll long long
    #define ull unsigned long long
    #define mod (1ll<<64ll)
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    
    using namespace std;
    
    const double g=10.0,eps=1e-7;
    const int N=30+10,maxn=100+10,inf=0x3f3f3f;
    
    struct Node{
        int row,col;
        ull a[N][N];
    };
    Node mul(Node x,Node y)
    {
        Node ans;
        ans.row=x.row;ans.col=y.col;
        memset(ans.a,0,sizeof ans.a);
        for(int i=0;i<x.row;i++)
            for(int j=0;j<x.col;j++)
                for(int k=0;k<y.col;k++)
                    ans.a[i][k]=(ans.a[i][k]+x.a[i][j]*y.a[j][k]);
        return ans;
    }
    Node quick_mul(Node x,ll n)
    {
        Node ans;
        ans.row=x.row;ans.col=x.col;
        memset(ans.a,0,sizeof ans.a);
        for(int i=0;i<ans.row;i++)ans.a[i][i]=1;
        while(n)
        {
            if(n&1)ans=mul(ans,x);
            x=mul(x,x);
            n/=2;
        }
        return ans;
    }
    struct Trie{
        int tot,root;
        int Next[N][26],fail[N];
        bool End[N];
        int newnode()
        {
            for(int i=0;i<26;i++)
                Next[tot][i]=-1;
            End[tot]=0;
            return tot++;
        }
        void init()
        {
            tot=0;
            root=newnode();
        }
        void insertstring(string s)
        {
            int now=root;
            for(int i=0;i<s.size();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;
            int now=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]);
                    }
                }
            }
        }
        Node getmartix()
        {
            Node ans;
            ans.row=tot+1;ans.col=tot+1;
            memset(ans.a,0,sizeof ans.a);
            for(int i=0;i<tot;i++)
                for(int j=0;j<26;j++)
                    if(!End[Next[i][j]])
                        ans.a[i][Next[i][j]]++;
            for(int i=0;i<tot+1;i++)
                ans.a[i][tot]=1;
            return ans;
        }
        void debug()
        {
            for(int i = 0;i < tot;i++)
            {
                printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],End[i]);
                for(int j = 0;j < 26;j++)
                    printf("%2d",Next[i][j]);
                printf("]
    ");
            }
        }
    };
    Trie ac;
    string s;
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        int m;
        ll n;
        while(cin>>m>>n)
        {
            ac.init();
            for(int i=0;i<m;i++)
            {
                cin>>s;
                ac.insertstring(s);
            }
            ac.build();
           // ac.debug();
            Node ans=ac.getmartix();
            ans=quick_mul(ans,n);
        /*    for(int i=0;i<ans.row;i++)
            {
                for(int j=0;j<ans.col;j++)
                    cout<<ans.a[i][j]<<" ";
                cout<<endl;
            }*/
            ull p=0;
            for(int i=0;i<ans.row;i++)
                p+=ans.a[0][i];
            p--;
            ans.row=2;ans.col=2;
            ans.a[0][0]=26;ans.a[0][1]=0;
            ans.a[1][0]=ans.a[1][1]=1;
            ans = quick_mul(ans,n);
            ull res=ans.a[1][0]+ans.a[0][0];
            res--;
            //cout<<res<<" "<<p<<endl;
            cout<<res-p<<endl;
        }
        return 0;
    }
    /********************
    2 3
    aa ab
    53324 18174
    35150
    1 2
    a
    702 650
    52
    ********************/
    View Code
  • 相关阅读:
    C/C++解题常用STL大礼包 含vector,map,set,queue(含优先队列) ,stack的常用用法
    PAT甲级1018留坑——第一个测试点未过(Dijikstar+Dfs)
    PAT甲级1019水题飘过
    微信该公众号提供的服务出现故障
    The valid characters are defined in RFC 7230 and RFC 3986
    eclipse中Web Deployment Assembly与build path作用
    Invalid bound statement (not found)
    springmvc获取bean
    mac/linux查询网络端口占用
    SiteMesh使用(2.4.2)
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/7575124.html
Copyright © 2020-2023  润新知