ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【ybtoj高效进阶 21175】DNA 序列(SAM)

2021-11-03 21:01:34  阅读:209  来源: 互联网

标签:21175 DNA 进阶 sz int len son fa np


DNA 序列

题目链接:ybtoj高效进阶 21175

题目大意

给你一个由四种字符组成的字符串,然后问你长度为 k 的子串中出现次数最多的串的出现次数。
1<=k<=10

思路

其实因为 1 ⩽ k ⩽ 10 1\leqslant k\leqslant 10 1⩽k⩽10,而且只有四种字符,所以我们可以直接暴力搞。

但我直接用 SAM 了。
(因为用 SAM 也是模板题)

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long

using namespace std;

struct node {
	int son[4], len, fa;
	ll sz;
}d[10000001];
char s[5000001];
int sn, k, lst, tot;
ll ans;

int ck(char c) {
	if (c == 'A') return 0;
	if (c == 'T') return 1;
	if (c == 'G') return 2;
	return 3;
}

void insert(int x) {
	int p = lst;
	int np = ++tot;
	lst = np;
	d[np].len = d[p].len + 1;
	d[np].sz = 1;
	for (; p && !d[p].son[x]; p = d[p].fa) d[p].son[x] = np;
	if (!p) d[np].fa = 1;
		else {
			int q = d[p].son[x];
			if (d[q].len == d[p].len + 1) d[np].fa = q;
				else {
					int nq = ++tot;
					d[nq] = d[q];
					d[nq].sz = 0;
					d[nq].len = d[p].len + 1;
					d[q].fa = d[np].fa = nq;
					for (; p && d[p].son[x] == q; p = d[p].fa) d[p].son[x] = nq;
				}
		}
}

int tong[5000001], xl[10000001];

void DP() {
	for (int i = 1; i <= tot; i++)
		tong[d[i].len]++;
	for (int i = 1; i <= sn; i++)
		tong[i] += tong[i - 1];
	for (int i = 1; i <= tot; i++) {
		xl[tong[d[i].len]--] = i;
	}
	
	for (int i = tot; i >= 1; i--)
		d[d[xl[i]].fa].sz += d[xl[i]].sz;
}

int main() {
//  freopen("dna.in", "r", stdin);
//	freopen("dna.out", "w", stdout);
	
	scanf("%s", s + 1);
	sn = strlen(s + 1);
	scanf("%d", &k);
	
	lst = tot = 1;
	for (int i = 1; i <= sn; i++) {
		insert(ck(s[i]));
	}
	
	DP();
	
	for (int i = 1; i <= tot; i++) {
		if (d[i].len >= k && d[d[i].fa].len + 1 <= k) {
			ans = max(ans, d[i].sz);
		}
	}
	printf("%lld", ans);
	
	return 0;
}

标签:21175,DNA,进阶,sz,int,len,son,fa,np
来源: https://blog.csdn.net/weixin_43346722/article/details/121130374

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有