HDU 2243 postgraduate entrance-word complex (AC automation + matrix)

Source: Internet
Author: User

Hi, Chinese question... I won't talk about it.


First, poj 2778 knows that the AC automatic mechanism can be used to find the number of non-virus strings in strings with a length of L.

The general idea of poj 2778 is to first create an AC automatic machine with all the virus strings, and then connect all non-word nodes on the AC automatic machine to an edge.

In Discrete Mathematics, if [I] [J] in matrix A represents the number of methods that an I node can walk to a j node through an edge.

Then the [I] [J] of the matrix A * A indicates the number of methods that an I node can go to a j node through two edges.

Now that we know this method, we have a clear requirement.

Ans = 26 + 26 ^ 2 + 26 ^ 3 + .... + 26 ^ L-the number of non-virus strings with a length of 1-the number of non-virus strings with a length of 2 -... -The length is the number of non-virus strings.


Solve two problems

Modulo 2 ^ 64. Knowing that 2 ^ 64 is the maximum value of long, we can directly open it into unsigned long... and then rest assured that overflow is the modulus.

We know that the matrix ^ L requires all the sums, and we need to use a matrix in the matrix. That is, the sum of matrices.


#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>#define N 35using namespace std;typedef unsigned long long ll;const char tab = 'a';const int max_next = 26;struct trie{    struct trie *fail;    struct trie *next[max_next];    int isword;    int index;};struct AC{    trie *que[100005],*root,ac[100005];    int head,tail;    int idx;    trie *New()    {        trie *temp=&ac[idx];        for(int i=0;i<max_next;i++)temp->next[i]=NULL;        temp->fail=NULL;        temp->isword=0;        temp->index=idx++;        return temp;    }    void init()    {        idx=0;        root=New();    }    void Insert(trie *root,char *word,int len){        trie *t=root;        for(int i=0;i<len;i++){            if(t->next[word[i]-tab]==NULL)                t->next[word[i]-tab]=New();            t=t->next[word[i]-tab];        }        t->isword++;    }    void acbuild(trie *root){        int head=0,tail=0;        que[tail++]=root;        root->fail=NULL;        while(head<tail){            trie *temp=que[head++],*p;            for(int i=0;i<max_next;i++){                 if(temp->next[i]){                    if(temp==root)temp->next[i]->fail=root;                    else {                        p=temp->fail;                        while(p!=NULL){                            if(p->next[i]){                                temp->next[i]->fail=p->next[i];                                break;                            }                            p=p->fail;                        }                        if(p==NULL)temp->next[i]->fail=root;                    }                    if(temp->next[i]->fail->isword)temp->next[i]->isword++;                    que[tail++]=temp->next[i];                 }                 else if(temp==root)temp->next[i]=root;                 else temp->next[i]=temp->fail->next[i];            }        }    }    void tra()    {        for(int i=0;i<idx;i++)        {            if(ac[i].fail!=NULL)printf("fail = %d ",ac[i].fail->index);            for(int k=0;k<max_next;k++)                printf("%d ",ac[i].next[k]->index);            puts("");        }    }}sa;struct matrix{    int r,c;    ll data[N][N];    matrix(){}    matrix(int _r,int _c):r(_r),c(_c){memset(data,0,sizeof data);}    friend matrix operator * (const matrix A,const matrix B)    {        matrix res;        res.r=A.r;res.c=B.c;        memset(res.data,0,sizeof res.data);        for(int i=0;i<A.r;i++)        {            for(int j=0;j<B.c;j++)            {                for(int k=0;k<A.c;k++)                {                    if(A.data[i][k] && B.data[k][j]){                        res.data[i][j]+=A.data[i][k]*B.data[k][j];                        //res.data[i][j]%=mod;                    }                }            }        }        return res;    }    friend matrix operator + (const matrix A,const matrix B)    {        matrix res;        res.r=A.r;res.c=A.c;        memset(res.data,0,sizeof res.data);        for(int i=0;i<A.r;i++)        {            for(int j=0;j<A.c;j++)            {                res.data[i][j]=A.data[i][j]+B.data[i][j];                //res.data[i][j]%=mod;            }        }        return res;    }    friend matrix operator - (const matrix A,const matrix B)    {        matrix res;        res.r=A.r;res.c=A.c;        memset(res.data,0,sizeof res.data);        for(int i=0;i<A.r;i++)        {            for(int j=0;j<A.c;j++)            {                res.data[i][j]=A.data[i][j]-B.data[i][j];                //res.data[i][j]=(res.data[i][j]%mod+mod)%mod;            }        }        return res;    }    friend matrix operator ^ (matrix A,int n)    {        matrix res;        res.r=A.r;res.c=A.c;        memset(res.data,0,sizeof res.data);        for(int i=0;i<A.r;i++)res.data[i][i]=1;        while(n)        {            if(n&1)res=res*A;            A=A*A;            n>>=1;        }        return res;    }    void print()    {        for(int i=0;i<r;i++)        {            for(int j=0;j<c;j++)                printf("%d ",data[i][j]);            puts("");        }    }}E,zero;char word[10];struct supermatrix{    matrix ret[2][2];    friend supermatrix operator * (const supermatrix A,const supermatrix B)    {        supermatrix res;        for(int i=0;i<2;i++)            for(int j=0;j<2;j++)res.ret[i][j]=zero;        for(int i=0;i<2;i++)        {            for(int j=0;j<2;j++)            {                for(int k=0;k<2;k++)                {                    res.ret[i][j]=res.ret[i][j]+A.ret[i][k]*B.ret[k][j];                }            }        }        return res;    }    friend supermatrix operator + (const supermatrix A,const supermatrix B)    {        supermatrix res;        for(int i=0;i<2;i++)for(int j=0;j<2;j++)res.ret[i][j]=zero;        for(int i=0;i<2;i++)        {            for(int j=0;j<2;j++)            {                res.ret[i][j]=A.ret[i][j]+B.ret[i][j];            }        }        return res;    }    friend supermatrix operator ^ (supermatrix A,ll n)    {        supermatrix res;        for(int i=0;i<2;i++)for(int j=0;j<2;j++)res.ret[i][j]=zero;        for(int i=0;i<2;i++)res.ret[i][i]=E;        while(n)        {            if(n&1)res=res*A;            A=A*A;            n>>=1;        }        return res;    }};int main(){    int n,L;    while(scanf("%d%d",&n,&L)!=EOF)    {        sa.init();        for(int i=1;i<=n;i++)        {            scanf("%s",word);            sa.Insert(sa.root,word,strlen(word));        }        sa.acbuild(sa.root);        E=matrix(sa.idx,sa.idx);        for(int i=0;i<N;i++)E.data[i][i]=1;        zero=matrix(sa.idx,sa.idx);        matrix origin=matrix(sa.idx,sa.idx);        for(int i=0;i<sa.idx;i++)        {            if(sa.ac[i].isword==0)            {                for(int d=0;d<max_next;d++)                {                    int temp=sa.ac[i].next[d]->index;                    if(sa.ac[i].next[d]->isword==0)                    {                        origin.data[i][temp]++;                    }                }            }        }        supermatrix A;        A.ret[0][0]=A.ret[0][1]=E;        A.ret[1][0]=zero;        A.ret[1][1]=origin;        A=A^L;        supermatrix f;        f.ret[0][0]=f.ret[0][1]=f.ret[1][1]=zero;        f.ret[1][0]=origin;        matrix fans=A.ret[0][0]*zero+A.ret[0][1]*origin;        ll ans=0;        for(int i=0;i<sa.idx;i++)        {            if(sa.ac[i].isword==0)            {                ans+=fans.data[0][i];            }        }        matrix I=matrix(2,2);        I.data[0][0]=I.data[0][1]=1;        I.data[1][1]=26;        I.data[1][0]=0;        I=I^L;        printf("%I64u\n",I.data[0][1]*26-ans);    }    return 0;}


HDU 2243 postgraduate entrance-word complex (AC automation + matrix)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.