zoukankan      html  css  js  c++  java
  • [JSOI2007]文本生成器

    容斥原理, 求出所有的情况减去不可读的情况就是可读的文本数了a
    找不可读文本的数量类似于病毒那一题趴我觉得
    DP转移的话...
    用f[i][j] 表示当前在节点j, 且串长为i时的情况

    #include <bits/stdc++.h>
    using namespace std;
    const int MOD = 1e4 + 7;
    const int N = 20005;
    
    int n, m, cnt;
    int f[N][10000];//f[i][j] : 当前在节点j, 且串长为i时的情况
    struct {
    	int vis[26];
    	int fail;
    	int end;
    } AC[N];
    
    void build(string s) {
    	int now = 0;
    	for(int i = 0; i < s.size(); i++) {
    		if(!AC[now].vis[s[i] - 'A']) 
    			AC[now].vis[s[i] - 'A'] = ++cnt;
    		now = AC[now].vis[s[i] - 'A'];
    	}
    	AC[now].end = 1;
    }
    void Get_fail() {
    	queue<int> q;
    	for(int i = 0; i < 26; i++) 
    		if(AC[0].vis[i]) {
    			AC[AC[0].vis[i]].fail = 0;
    			q.push(AC[0].vis[i]);
    		}
    	while(!q.empty()) {
    		int u = q.front(); q.pop();
    		for(int i = 0; i < 26; i++) {
    			if(AC[u].vis[i]) {
    				AC[AC[u].vis[i]].fail = AC[AC[u].fail].vis[i];
    				AC[AC[u].vis[i]].end |= AC[AC[AC[u].vis[i]].fail].end;
    				q.push(AC[u].vis[i]);
    			}
    			else AC[u].vis[i] = AC[AC[u].fail].vis[i];
    		}
    	}
    }
    int main() {
    	ios :: sync_with_stdio(0);
    
    	string s;
    	cin >> n >> m;
    	for(int i = 1; i <= n; i++)
    		cin >> s, build(s);
    	Get_fail();	
    	f[0][0] = 1;
    	for(int i = 1; i <= m; i++) 
    		for(int j = 0; j <= cnt; j++) 
    			for(int k = 0; k < 26; k++) 
    				if(!AC[AC[j].vis[k]].end)
    					(f[i][AC[j].vis[k]] += f[i - 1][j] ) %= MOD;
    	int ans = 0;
    	for(int i = 0; i <= cnt; i++)
    		(ans += f[m][i] ) %= MOD;
    	int sum = 26;
    	for(int i = 1; i < m; i++)
    		(sum *= 26) %= MOD;
    	cout << (sum - ans + MOD) % MOD;
    	return 0;
    }
    
  • 相关阅读:
    什么是进程
    进程控制
    MMAP文件内存映射
    I/O多路转接模型
    LINUX创建管道文件
    文件描述符复制
    LINUX改变文件大小
    类作用域
    LINUX文件定位
    War of the Corporations CodeForces
  • 原文地址:https://www.cnblogs.com/hyxss/p/13883341.html
Copyright © 2011-2022 走看看