P9196 [JOI Open 2016] 销售基因链 / Selling RNA Strands 题解

P9196 JOI Open 2016 销售基因链 / Selling RNA Strands 题解

思路

考虑映射,将基因库的字符串 SiS_iSi 映射成 Si#SiS_i\#S_iSi#Si 的形式,对于询问 P,QP,QP,Q 映射成 Q#PQ\#PQ#P 的形式,那么就相当于问每个询问串在基因库中出现的次数,直接跑 AC 自动机多模匹配即可。

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n;
int ch[5000010][5],ed[5000010],fail[5000010],c[255],id;
int ip[100010];
void ins(string s,int x){
	int p=0;
	for(int i=0;i<s.size();i++){
		int j=c[s[i]];
		if(!ch[p][j])ch[p][j]=++id;
		p=ch[p][j];
	}
	ip[x]=p;
}
int q[4100010],l=1,r;
void build(){
	for(int i=0;i<5;i++)if(ch[0][i])q[++r]=ch[0][i];
	while(l<=r){
		int x=q[l++];
		for(int i=0;i<5;i++){
			int &y=ch[x][i];
			if(!y)y=ch[fail[x]][i];
			else fail[y]=ch[fail[x]][i],q[++r]=y;
		}
	}
}
vector<int> G[5000010];
void query(string s){
	int p=0;
	for(int i=0;i<s.size();i++){
		int j=c[s[i]];
		p=ch[p][j];
		ed[p]++;
	}
}
void dfs(int x){
	for(int y:G[x]){
		dfs(y);
		ed[x]+=ed[y];
	}
}
string s[100010];
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0);
	c['A']=0;c['G']=1;c['U']=2;c['C']=3;c['#']=4;
	int q;
	cin>>n>>q;
	for(int i=1;i<=n;i++){
		cin>>s[i];
		s[i]=s[i]+"#"+s[i];//字符串映射
	}
	dfs(0);
	for(int i=1;i<=q;i++){
		string s,t;
		cin>>s>>t;
		s=t+"#"+s;//字符串映射
		ins(s,i);
	}
	build();//建AC自动机
	for(int i=1;i<=id;i++)G[fail[i]].push_back(i);
	for(int i=1;i<=n;i++)query(s[i]);//多模匹配
	dfs(0);
	for(int i=1;i<=q;i++){
		cout<<ed[ip[i]]<<'\n';
	}
	return 0;
}
相关推荐
HAPPY酷17 分钟前
C++ 内存泄漏排查:从裸 new 到 RAII 修复,附 ASan 实战
开发语言·c++
易小尊26 分钟前
Dixon-Coles 的 τ 函数,我写错了三次
算法
凯瑟琳.奥古斯特1 小时前
力扣1015C++解法技巧
c++·算法·leetcode·链表·职场和发展
seowmt2 小时前
GEO效果该什么时候看数据:从立项到复盘的时间线复盘
算法·ip·seo·geo·faq
悠仁さん2 小时前
【算法C++】双指针(一)
数据结构·c++·算法
jimy12 小时前
lvalue、xvalue、prvalue(二):引用是哪一类?
开发语言·c++·1024程序员节
小豆庄2 小时前
本地视频脱敏的追踪系统踩坑——车牌过滤、转场误判与ID冲突排查
人工智能·算法·目标检测·音视频·视频·敏捷流程·纹理贴图
忆挽篱笙歌2 小时前
进程替换函数与shenll命令行解释器
前端·javascript·算法
YukiRinLL2 小时前
字符串存储与 BF、KMP 匹配算法
数据结构·算法
小超人诞生日记2 小时前
Linux:环境变量 & 进程虚拟地址空间
linux·算法