必赢亚洲手机app下载


必赢亚洲手机app制伏拖延的11种艺术

战略性人生

字符串构造的dp

1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory
Limit: 162 MB
Submit: 4305  Solved: 2637
[Submit][Status][Discuss]

Description

  阿申准备申请参与GT考试,准考证号为N位数X1X2….Xn(0<=Xi<=9),他不期望准考证号上出现不吉祥的数字。
他的不吉祥数学A1A2…Am(0<=Ai<=9)有M位,不出新是指X1X2…Xn中平素不恰好一段等于A1A2…Am.
A1和X1可以为
0

Input

  第一行输入N,M,K.接下来一行输入M位的数。
N<=10^9,M<=20,K<=1000

Output

  阿申想通晓不出现不吉祥数字的编号有多少种,输出模K取余的结果.

Sample Input

4
3 100
111

Sample Output

81

设f[i][j]意味着到第i个职位后缀为不吉祥数字[1….j]的方案数

我们令a[i][j]意味着不吉利数字由i号位转j号位的方案数

显然f[i][j] = f[i – 1][0] *
a[0][j] + f[i – 1][1] * a[1][j] + f[i – 1][2] *
a[2][j]……

但N很大大家无法平昔推

着眼出那是f的一个齐次式,所以转矩阵快速幂

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define fo(i,x,y) for (int i = (x); i <= (y); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 100005,maxm = 25,INF = 1000000000;

int n,m,P;
char s[maxn];
int nxt[maxn];

struct Matrix{
    int s[maxm][maxm],n,m;
    Matrix() {memset(s,0,sizeof(s)); n = m = 0;}
}A;

inline Matrix operator * (const Matrix& a,const Matrix& b){
    Matrix c;
    if (a.m != b.n) return c;
    c.n = a.n; c.m = b.m;
    for (int i = 0 ; i < c.n; i++)
        for (int j = 0; j < c.m; j++)
            for (int k = 0; k < a.m; k++)
                c.s[i][j] = (c.s[i][j] + a.s[i][k] * b.s[k][j]) % P;
    return c;
}

inline Matrix qpow(Matrix a,LL b){
    Matrix ans; ans.n = ans.m = a.n;
    for (int i = 0; i < ans.n; i++) ans.s[i][i] = 1;
    for (; b; b >>= 1,a = a * a)
        if (b & 1) ans = ans * a;
    return ans;
}

void getf(){
    for (int i = 1 ; i < m; i++){
        int j = nxt[i];
        while (j && s[j] != s[i]) j = nxt[j];
        nxt[i + 1] = s[j] == s[i] ? j + 1 : 0;
    }
}

void init(){
    cin>>n>>m>>P>>s;
    getf();
    for (int i = 0; i < m; i++){
        for (char j = '0'; j <= '9'; j++){
            int k = i;
            while (k && s[k] != j) k = nxt[k];
            if (s[k] == j) k++;
            if (k != m) A.s[i][k]++;
        }
    }
    A.n = A.m = m;
}

void solve(){
    Matrix F = qpow(A,n),Ans;
    Ans.n = 1; Ans.m = m;
    Ans.s[0][0] = 1;
    Ans = Ans * F;
    int ans = 0;
    for (int i = 0; i < m; i++)
        ans = (ans + Ans.s[0][i]) % P;
    cout<<ans<<endl;
}

int main()
{
    init();
    //cout<<"h"<<endl;
    solve();
    return 0;
}

1030: [JSOI2007]文本生成器

Time Limit: 1 Sec  Memory
Limit: 162 MB
Submit: 5248  Solved: 2166
[Submit][Status][电脑软件,Discuss]

Description

  JSOI交给队员ZYX一个任务,编制一个称呼“文本生成器”的电脑软件:该软件的使用者是一对幼稚人群,
她俩现在采取的是GW文本生成器v6版。该软件可以轻易生成一些稿子―――总是生成一篇长度固定且完全自由的文
章——
也就是说,生成的篇章中各种字节都是一点一滴自由的。假使一篇小说中至少含有使用者们询问的一个单词,
那么大家说那篇小说是可读的(大家称文章a包蕴单词b,当且仅当单词b是小说a的子串)。可是,尽管根据那样的
正式,使用者现在应用的GW文本生成器v6版所生成的作品也是大致全盘不可读的?。ZYX须求提出GW文本生成器
v6
变更的享有文件中可读文本的数额,以便可以成功博得v7更新版。你能匡助他吗?

Input

  输入文件的率先行包括三个正整数,分别是使用者明白的单词总数N (<=
60),GW文本生成器 v6生成的文本固
定长度M;以下N行,每一行蕴涵一个使用者精通的单词。这里拥有单词及文件的尺寸不会超过100,并且只可能包
含英文大写字母A..Z

Output

  一个整数,表示可能的稿子总数。只要求了然结果模10007的值。

Sample Input

2
2
A
B

Sample Output

100

一眼看上去特其他像,但变成了八个字符串的合营,就改为AC自动机

f[i][j]意味着到i地方后缀为trie树中的j节点的方案数

显然f[i][j]可以由f[i –
1][k]转来,只要存在ch[k][…] = j的指针

我们就正向dp,推出f,要留心的是有tag标记成功匹配的地点是无法算的,且若fail指针指向一个tag标记的节点,那么这么些节点也要打tag标记,fail指向的字符串一定是时下的后缀,后缀存在法定字符串,当然非常了

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define fo(i,x,y) for (int i = (x); i <= (y); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 10005,maxm = 105,INF = 1000000000,P = 10007;

int N,M,ch[maxn][26],tag[maxn],fail[maxn],siz = 0,f[maxm][maxn];
char A[maxm];
void insert(){
    int n = strlen(A),u = 0,id;
    for (int i = 0; i < n; i++){
        id = A[i] - 'A';
        u = ch[u][id] ? ch[u][id] : ch[u][id] = ++siz;
    }
    tag[u] = true;
}
void getf(){
    queue<int> q;
    for (int i = 0; i < 26; i++) if (ch[0][i]) q.push(ch[0][i]);
    int u,v;
    while (!q.empty()){
        u = q.front();
        q.pop();
        for (int i = 0; i < 26; i++){
            v = ch[u][i];
            if (!v) ch[u][i] = ch[fail[u]][i];
            else fail[v] = ch[fail[u]][i],q.push(v);
        }
        if (tag[fail[u]]) tag[u] = true;
    }
}
int main()
{
    cin >> N >> M;
    REP(i,N) scanf("%s",A),insert();
    getf(); f[0][0] = 1;
    for (int i = 0; i < M; i++){
        for (int j = 0; j <= siz; j++){
            if (tag[j] || !f[i][j]) continue;
            for (int k = 0; k < 26; k++){
                int v = ch[j][k];
                f[i + 1][v] = (f[i + 1][v] + f[i][j]) % P;
            }
        }
    }
    int ans = 1;
    REP(i,M) ans = ans * 26 % P;
    for (int i = 0; i <= siz; i++) if (!tag[i]) ans = (ans - f[M][i] + P) % P;
    cout<<ans<<endl;
    return 0;
}

相关文章

No Comments, Be The First!
近期评论
    功能
    网站地图xml地图