P3763-[TJOI2017]DNA

目录

P3763-[TJOI2017]DNA

加里敦大学的生物研究所,发现了决定人喜不喜欢吃藕的基因序列 SS,有这个序列的碱基序列就会表现出喜欢吃藕的性状,但是研究人员发现对碱基序列 SS,任意修改其中不超过 33 个碱基,依然能够表现出吃藕的性状。现在研究人员想知道这个基因在 DNA 链 S0S_0 上的位置。所以你需要统计在一个表现出吃藕性状的人的 DNA 序列 S0S_0 上,有多少个连续子串可能是该基因,即有多少个 S0S_0 的连续子串修改小于等于三个字母能够变成 SS

第一行有一个整数 TT,表示有几组数据。

每组数据第一行一个长度不超过 10510^5 的碱基序列 S0S_0

每组数据第二行一个长度不超过 10510^5 的吃藕基因序列 SS

TT 行,第 ii 行表示第 ii 组数据中,在 S0S_0中有多少个与 SS 等长的连续子串可能是表现吃藕性状的碱基序列。

1
2
3
1
ATCGCCCTA
CTTCA
1
2
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Problem: P3763 [TJOI2017]DNA
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3763
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// Author: Ybw051114
//
// Powered by CP Editor (https://cpeditor.org)

#include "ybwhead/SAM.h"
#include "ybwhead/ios.h"
CPTH::SAM<char> x;
string s, s1;
const char xx[5] = {'A', 'C', 'G', 'T'};
long long ans;
const int maxn = 2e5 + 10;
int cnt[maxn];
int m;
void dfs(register int u, register int len, register int pp)
{
    // yout << u << " " << len << " " << pp << endl;
    if (len > m)
        return (void)(ans += cnt[u]);
    CPTH::SAM<char>::SAMNode xxx = x[u];
    for (register int i = 0; i < 4; ++i)
    {
        if (!xxx[xx[i]])
            continue;
        if (s1[len - 1] == xx[i])
            dfs((int)xxx[xx[i]], len + 1, pp);
        else if (pp < 3)
            dfs((int)xxx[xx[i]], len + 1, pp + 1);
    }
}
int main()
{
    int TTT;
    yin >> TTT;
    while (TTT--)
    {
        yin >> s >> s1;
        m = s1.size();
        x.clear();
        memset(cnt, 0, sizeof(cnt));
        for (auto c : s)
            cnt[x.append(c)] = 1;
        // x = CPTH::SAM<>(s);
        x.buildTree();
        function<void(int)> dfs1 = [&](int u) {
            for (auto v : x.children(u))
            {
                dfs1(v);
                cnt[u] += cnt[v];
            }
        };
        dfs1(0);
        ans = 0;
        dfs(0, 1, 0);
        yout << ans << endl;
    }
    return 0;
}
来发评论吧~
Powered By Valine
v1.4.14