• [TJOI2018]碱基序列


    [TJOI2018 碱基序列](https://www.luogu.com.cn/problem/P4591)
    
    偷懒直接 SAM 上 DP。
    
    设 dp(i,j) 表示用前 i 行氨基酸匹配到状态 j 的方案数。
    
    由于这个题面比较玄学, 复杂度就挺玄学, 随手加点剪枝就可以很快。
    
    ```cpp
    #include <bits/stdc++.h>
    typedef long long LL;
    using namespace std;
    
    const int mo = 1e9 + 7;
    
    int siz[20113];
    struct node {
    	int f, len, t[26];
    } t[20113];
    int a[20113];
    
    int tot = 1, las = 1;
    void extnd (int c) {
    	int np = ++ tot, p = las; las = np;
    	t[np].len = t[p].len + 1;
    	for (; p && !t[p].t[c]; p = t[p].f) t[p].t[c] = np;
    	if (!p) t[np].f = 1;
    	else {
    		int v = t[p].t[c];
    		if (t[v].len == t[p].len + 1) t[np].f = v;
    		else {
    			int nv = ++ tot; t[nv] = t[v];
    			t[nv].len = t[p].len + 1;
    			for (; p && t[p].t[c] == v; p = t[p].f) t[p].t[c] = nv;
    			t[np].f = t[v].f = nv;
    		}
    	}
    	siz[np] += 1;
    }
    
    int n;
    char s[10003];
    
    LL dp[103][20113];
    bool cmp (int s1, int s2) { return t[s1].len < t[s2].len; }
    
    int main()
    {
    	scanf ("%d%s", & n, s);
    	int len = strlen (s);
    	for (int i = 0; i < len; ++ i) extnd (s[i] - 'A');
    	dp[0][1] = 1ll;
    	for (int id = 1; id <= n; ++ id)
    	{
    		int k;
    		scanf ("%d", &k);
    		for (int i = 0; i < k; ++ i) {
    			scanf ("%s", s); int sl = strlen (s); if (sl > len) continue;
    			for (int sta = 1; sta <= tot; ++ sta) if(dp[id - 1][sta]) {
    				int now = sta;
    				// tran
    				for (int j = 0; j < sl; ++ j) { now = t[now].t[s[j] - 'A']; if (!now) break; }
    				if (now) dp[id][now] += dp[id - 1][sta], dp[id][now] %= mo;
    			}
    		}
    	}
    	for (int i = 1; i <= tot; ++ i) a[i] = i;
    	sort (a + 1, a + 1 + tot, cmp);
    	for (int i = tot; i >= 1; -- i) if (t[a[i]].f) siz[t[a[i]].f] += siz[a[i]];
    	LL ans = 0ll;
    	for (int i = 1; i <= tot; ++ i) ans += (LL)dp[n][i] * siz[i] % mo, ans = ans % mo;
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    加密算法
    git 误操作
    element项目发布
    node命令
    计划
    第一次碰见类似留几手的段子手
    【vue】---猫眼项目中使用js组件的时候-------loading 加载 无法移除的原因---------
    【异步】---异步解决方案---
    【问题-方法】---buffer---解决方法,butter 文件转字符串
    【大脑】--如何让大脑快速记忆
  • 原文地址:https://www.cnblogs.com/tztqwq/p/14472974.html
Copyright © 2020-2023  润新知