HDU 3962 / HIT 3045 Microgene--ac自动机 动态规划

来源:互联网 发布:tensorflow 二次开发 编辑:程序博客网 时间:2024/04/27 21:53

http://acm.hdu.edu.cn/showproblem.php?pid=3962

http://acm.hit.edu.cn/judge/show.php?Proid=3045

 

这场赛真悲剧 前4小时没交题 一直在想那个找环的题 结果最后试了下居然暴力就能过>.

 

A了那个找环题 同学就上去把积分过了  然后我看B题 看完后AC自动机能搞

状态转移方程也很明显

dp[l][sta][0]=∑dp[l-1][psta][0]

dp[l][sta][1]=∑dp[l-1][psta][1]

(sta为合法串)

 

dp[l][sta][0]=0;

dp[l][sta][1]=∑dp[l-1][psta][0]

(sta为非法串)

 

本来打算先在机器上线性递推验证正确然后再改成矩阵的

尼玛的 滚动数组忘初始化了 找了1个小时都没找出来>...

然后就悲剧了...

由于状态转移是+=的转移 而且用的滚动数组 一个数组会重复利用 下次用之前应该把当前的数组清0

但转移若是取上次的最值之类的就不会出现这种状况 所以这次没意识出来

 

加上初始化后答案就对了 只是会超时 改成矩阵形式 因为是齐次线性递推的 矩阵行列就是字典树节点数*2 然后m^3logN速度0.02s AC

 

 

#include<cstdio>#include<cstring>#include<algorithm> using namespace std;#define KIND 4#define MAXN 66#define INF 0x3fffffff#define MOD 10007#define FF(i,n) for(i=0;i<n;i++)int N;struct IM{    int el[MAXN][MAXN];};IM sgl,bas;IM operator * (IM &x,IM &y){    IM r;    int i,j,k;    FF(i,N)        FF(j,N)        r.el[i][j]=0;    FF(i,N)        FF(k,N)        if(x.el[i][k])            FF(j,N)            if(y.el[k][j]){                r.el[i][j]+=x.el[i][k] * y.el[k][j];if(r.el[i][j]>=MOD)r.el[i][j]%=MOD;}    return r;}IM operator ^ (IM x,int m){    IM r=sgl;    for(;m;m>>=1)    {        if(m&1)            r=r*x;        x=x*x;    }    return r;}struct Node{    int fail;    bool end;    int next[KIND];    void init()    {        fail=-1;        end=0;        memset(next,-1,sizeof(next));    }}node[MAXN];int q[MAXN<<1];int head,tail;int sz; void init(){    sz=0;    node[0].init();}int Index(char c){    switch(c)    {        case 'A':return 0;        case 'G':return 1;        case 'C':return 2;        case 'T':return 3;    }    return 0;}void Insert(char *str){    int p=0;    for(int i=0;str[i];i++)    {        if(node[p].end)            break;        int index=Index(str[i]);        if(node[p].next[index]==-1)        {            node[p].next[index]=++sz;            node[sz].init();        }        p=node[p].next[index];    }    node[p].end=1;}void Build_AC(){    int temp;    int p=0;     head=tail=0;    q[tail++]=p;    while(head<tail)    {        temp=q[head++];        for(int i=0;i<KIND;i++)        {            p=node[temp].next[i];            if(p!=-1)            {                if(!temp)                    node[p].fail=0;                else                {                    node[p].fail=node[node[temp].fail].next[i];                    if(node[node[p].fail].end)                        node[p].end=1;                }                q[tail++]=p;            }            else            {                if(!temp)                    node[temp].next[i]=0;                else                    node[temp].next[i]=node[node[temp].fail].next[i];            }        }    }}int power(int a,int n){    int ret;    for(ret=1;n;n>>=1)    {        if(n&1)            ret=ret*a%MOD;        a=a*a%MOD;    }    return ret%MOD;} int main(){    int n,l,i,j;    int casenum=0;    char words[12];     while(~scanf("%d%d",&n,&l))    {        init();        for(i=1;i<=n;i++)        {            scanf("%s",words);            Insert(words);        }        Build_AC();N=(sz+1)<<1;for(i=0;i<N;i++)for(j=0;j<N;j++){sgl.el[i][j]=i==j;bas.el[i][j]=0;}for(i=0;i<=sz;i++){for(j=0;j<KIND;j++){if(!node[node[i].next[j]].end){bas.el[node[i].next[j]*2][i*2]++;bas.el[node[i].next[j]*2+1][i*2+1]++;}else{bas.el[node[i].next[j]*2+1][i*2]++;}}}IM mat=bas^l;int s=0;for(i=0;i<N;i++){s+=mat.el[i][0];if(s>=MOD)s%=MOD;}int total=power(4,l);int ans=(total-s)%MOD+MOD;printf("%d\n",ans%MOD);    }    return 0;}


 

 

原创粉丝点击