HU 2243−−−−−A−C自動機+マトリックス乗算+行列式


タイトルの住所:http://acm.hdu.edu.cn/showproblem.php?pid=2243
タイトルの意味:
n文字列をあげて長さLをあげます.
Lを超えないすべての文字列の中で(a~z)どれぐらいの文字列がありますか?少なくとも一つの文字列が含まれていますか?
意味がはっきりしました.次は解法です.この問題はPOJ 2778と似ています.詳しくは以下の通りです.http://blog.csdn.net/dr5459/article/details/8971626
じゃ、私達は自動機を作ります.POJ 2778と同じようにジャンプ行列Aを求めます.
それからA^1+A^2+A^3+A^4++A^Lを求めてきます.
でもこれは面倒くさいです.公式を紹介します.
HDU2243-----AC自动机+矩阵乘法+矩阵公式_第1张图片
この方法によって、ある行列の連続指数と、Eを減算すればいいです.
じゃ、L+1乗を求めればいいです.行列の最初の列を最後に求めます.だから、答えの中で-1だけでいいです.
これは不可能です.26^1+26^2++26^nを求めています.
減算すると結果になります.モデル2^64の方がいいですので、私達はユニックランドでlongすればいいです.
また、杭では%I 64 uを使います.そうでなければ、様々な間違いがあります.
コード:
#include
#include
#include
#include
#include
using namespace std;

#define ULL unsigned long long

const int maxnode = 6*6+5;
const int size=26;

struct AC
{
    int ch[maxnode][size];
    int f[maxnode];
    bool val[maxnode];
    int sz;

    void init()
    {
        memset(ch[0],-1,sizeof(ch[0]));
        sz=1;
        val[0]=false;
    }

    int idx(char c)
    {
        return c-'a';
    }

    void insert(char *s)
    {
        int len = strlen(s);
        int u=0;
        for(int i=0;i q;
        for(int i=0;i=n && i==j)
                tmp.m[i][j] = 1;
        }
    }
    maxtrixpower(l+1,tmp,tmp,ac.sz*2);
    ULL ans=0;
    for(int i=n;i<2*n;i++)
        ans+=tmp.m[0][i];
    return ans-1;
}


int main()
{
    ULL m,l;
    while(~scanf("%I64u%I64u",&m,&l))
    {
        ac.init();
        char op[10];
        for(int i=0;i