Foj 2299 Prefix

Posted wuyuanyuan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Foj 2299 Prefix相关的知识,希望对你有一定的参考价值。

Foj 2299 Prefix

题意

题解

代码

#include<cstdio>
#include<cmath>
#include<vector>
#include<iostream>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(a) (int)a.size()
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
#define all(a) a.begin(), a.end()
#define endl "n"
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;

const int N = 22, P = 1e9+7;

int n, m;
int f[N];
string s;

int kpow(int a, int b) {
    int res = 1;
    while(b) {
        if(b&1) res = 1ll*res*a%P;
        a = 1ll*a*a%P;
        b >>= 1;
    }
    return res;
}

inline int add(int a, int b) {
    a+=b;
    if(a>=P) a-=P;
    return a;
}
inline int sub(int a, int b) {
    a-=b;
    if(a<0) a+=P;
    return a;
}
inline int mul(int a, int b) {
    return 1ll*a*b%P;
}

struct Mat {
    static const int N = ::N;
    int a[N][N], n;
    Mat(){} Mat(int _n, int v) { n = _n; rep(i, 0, n) rep(j, 0, n) a[i][j] = i==j ? v : 0; }
    Mat operator * (const Mat &c) const {
        Mat res(n, 0);
        rep(i, 0, n) rep(j, 0, n) rep(k, 0, n) res.a[i][j] = add(res.a[i][j], mul(a[i][k], c.a[k][j]));
        return res;
    }
    Mat operator ^ (int b) const {
        Mat res(n, 1), a = *this;
        while(b) {
            if(b&1) res = res*a;
            a = a*a;
            b>>=1;
        }
        return res;
    }
};
struct Trie {
    static const int N = ::N, M = 26;
    int ne[N][M], fail[N], fa[N], rt, L, ed[N];
    void init() {
        fill_n(ne[fail[0] = N-1], M, 0);
        fill_n(ed, L, 0);
        L = 0;
        rt = newnode();
    }
    int newnode() {
        fill_n(ne[L], M, 0);
        return L++;
    }
    void add(string s) {
        int p = rt;
        rep(i, 0, sz(s)) {
            int c = s[i] - ‘A‘;
            if(!ne[p][c]) ne[p][c] = newnode(), fa[L-1] = p;
            p = ne[p][c];
        }
        ed[p] = 1;
    }
    void build() {
        vi v;v.pb(rt);
        rep(i, 0, sz(v)) {
            int c = v[i];
            rep(i, 0, M) ne[c][i] ? 
                v.pb(ne[c][i]), fail[ne[c][i]] = ne[fail[c]][i] :
                ne[c][i] = ne[fail[c]][i];
        }
    }
    Mat getMat() {
        Mat mat(L, 0);
        rep(i, 0, L) rep(j, 0, M) {
            int nex = ed[i] ? i : ne[i][j];
            ++mat.a[i][nex];
        }
        return mat;
    }
}ac;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int T;
    cin >> T;
    while(T--) {
        cin >> n >> m >> s;
        f[0] = kpow(26, n);
        rep(i, 1, m+1) {
            ac.init();
            ac.add(s.substr(0, i));
            ac.build();
            Mat res = ac.getMat() ^ n;
            f[i] = res.a[0][i];
        }
        rep(i, 0, m) f[i] = sub(f[i], f[i+1]);
        rep(i, 0, m+1) cout << f[i] << endl;
    }
    return 0;
}

以上是关于Foj 2299 Prefix的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段——声明函数

VSCode自定义代码片段8——声明函数

VSCode自定义代码片段——CSS动画

VSCode自定义代码片段(vue主模板)

vscode自定义代码片段

VSCode自定义代码片段3——url大全