Codeforces Round #137 (Div. 2) 222E. Decoding Genome

题意:测火星人的基因。输入一串字符串,长度为n,这个字符串中,有些字符对是不允许出现的,问符合题意的串的个数。

做法:b[i][0]=m*b[i-1][0]-sum(no);sum求的是在m个字母中每一个字母,以这个字母开头的字符对的数量的和。

   b[i][x](x>0)=b[i-1][0]+sum(ok*dp[i][y])若一个序列为<a,b>,那么ok[a][b]=-1;

这样就可以敲代码了

#include <iostream>
#include<cstdio>
#include<cstring>
#define mod 1000000007
#define LL long long
using namespace std;
class matrix
{
    public:
    int n,m;
    LL mat[55][55];
    void init()
    {
        memset(mat,0,sizeof(mat));
    }
     friend matrix operator *(const matrix &,const matrix &);
};
LL abs(LL a)
{
    return a>0?a:-a;
}
matrix  operator *(const matrix &a,const matrix &b)
{
    matrix tem;
    tem.n=a.n;
    tem.m=b.m;
    for(int i=0;i<a.n;i++)
      for(int j=0;j<b.m;j++)
      {
          tem.mat[i][j]=0;
          for(int t=0;t<a.m;t++)
            tem.mat[i][j]=((tem.mat[i][j]+(a.mat[i][t]%mod)*b.mat[t][j])%mod)%mod;
      }
      return tem;
}
matrix trans,mat,mtem;
void eat(char a,char b)
{
    if(a>='a'&&a<='z')a-='a'-1;
    else if(a>='A'&&a<='Z')a-='A'-27;
    if(b>='a'&&b<='z')b-='a'-1;
    else if(b>='A'&&b<='Z')b-='A'-27;//悲催,写了26
    trans.mat[0][a]--;
    trans.mat[b][a]=-1;
}
int main()
{
    LL n;
    int m,k;
    char s[3];
    scanf("%I64d%d%d",&n,&m,&k);
    mat.n=m+1;mat.m=1;
    while(k--)
    {
        scanf("%s",s);
        eat(s[0],s[1]);
    }
    trans.mat[0][0]=m;
    mat.mat[0][0]=m;
    trans.n=trans.m=mat.n=mat.m=m+1;
    for(int i=1;i<=m;i++)
    {
       trans.mat[i][0]=1;
       mat.mat[i][0]=1;
       mtem.mat[i][i]=1;
    }
    mtem.n=mtem.m=m+1;
    mtem.mat[0][0]=1;
    n--;
    while(n)
    {
        if(n&1)mtem=trans*mtem;
        trans=trans*trans;
        n>>=1;
    }
    trans=mtem;
    mat=trans*mat;
    LL ans=mat.mat[0][0];
    ans=(ans+mod)%mod;
    printf("%I64d\n",ans);
    return 0;
}


你可能感兴趣的:(Codeforces Round #137 (Div. 2) 222E. Decoding Genome)