Biology 题解

题意简述

初始有\(n\)个字符串,有\(m\)个操作,操作分为两种:

  1. 插入一个新的字符串,下标递增(\(n+1,n+2,n+3\dots\))。
  2. 查询\(k\)个字符串\(x_1,x_2,\dots,x_k\)的最长公共后缀长度。

\(N\le50000,M\le100000,2\le T\le10,|S_i|\le10000,\sum|S_i|\le1000000,总字符串数量\le100000\)。

Solution

的确是百年难得一见的水题。

先将字符串反转,变成一个最长公共前缀问题。

暴力是肯定不行的,这个显然要\(\log\)才过得去。

所以使用\(trie\)维护前缀,\(LCA\)查询最长公共前缀。

最长公共前缀的深度就是公共前缀的长度。

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#ifdef TH
#define debug printf("Now is %d\n",__LINE__);
#else
#define debug
#endif
using namespace std; template<class T>inline void read(T&x)
{
char ch=getchar();
int fu;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
x*=fu;
}
inline int read()
{
int x=0,fu=1;
char ch=getchar();
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') fu=-1,ch=getchar();
x=ch-'0';ch=getchar();
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*fu;
}
int G[55];
template<class T>inline void write(T x)
{
int g=0;
if(x<0) x=-x,putchar('-');
do{G[++g]=x%10;x/=10;}while(x);
for(int i=g;i>=1;--i)putchar('0'+G[i]);putchar('\n');
}
int n,m;
string reverse(string str)
{
for(int i=0;i<str.size()/2;i++)
{
swap(str[i],str[str.size()-i-1]);
}
// cout<<str<<endl;
return str;
}
struct Trie
{
int ch[1000010][26];
int cnt;
int v[100010];//将字符串编号映射到其末尾的节点
int dep[1000010],f[1000010][17];
Trie()
{
cnt=1;
memset(ch,0,sizeof(ch));
memset(v,0,sizeof(v));
}
void insert(string str,int pos)
{
int u=1;
for(int i=0;i<str.size();i++)
{
if(!ch[u][str[i]-'a']) ch[u][str[i]-'a']=++cnt;
dep[ch[u][str[i]-'a']]=dep[u]+1;
f[ch[u][str[i]-'a']][0]=u;
u=ch[u][str[i]-'a'];
for(int i=1;i<=16;i++) f[u][i]=f[f[u][i-1]][i-1];
}
v[pos]=u;
}
int LCA(int x,int y)
{
if(dep[x]<dep[y]) swap(x,y);
for(int i=16;i>=0;i--)
{
if(dep[f[x][i]]>=dep[y]) x=f[x][i];
}
if(x==y) return x;
for(int i=16;i>=0;i--)
{
if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
}
return f[x][0];
}
}trie;
int main()
{
// freopen("biology.in","r",stdin);
// freopen("biology.out","w",stdout);
n=read();
m=read();
string t;
for(int i=1;i<=n;i++) cin>>t,trie.insert(reverse(t),i);
int op,x,y;
while(m--)
{
op=read();
if(op==1)
{
cin>>t;
trie.insert(reverse(t),++n);
}
else
{
x=read();
y=trie.v[read()];
for(int i=2;i<=x;i++)
{
y=trie.LCA(y,trie.v[read()]);
}
write(trie.dep[y]);
}
}
return 0;
}
/*
5 5
zzj
pri
prime
ime
owaski
2 3 1 3 5
2 2 2 3
1 actri
2 2 3 4
2 3 2 6 5
*/

Biology 题解的更多相关文章

  1. 题解 biology

    传送门 赛时靠spfa求最长路骗了30pts spfa的时间复杂度是\(O(k|E|)\),不是\(O(k|N|)\)! dijkstra 时间复杂度\(O((n+m)logn)\) 特别注意这两个的 ...

  2. HDU 5590 ZYB's Biology 水题

    ZYB's Biology Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid ...

  3. HDU1560 DNA sequence(IDA*)题解

    DNA sequence Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) To ...

  4. Biology(湖南集训)

    题目大意:n个字符串,m个操作,可以插入字符串,也可以询问某T个字符串的最长后缀 题解:Trie+lca Trie树的插入与查询操作.把字符串反转就相当于求公共前缀. lca的深度就是公共前缀的长度. ...

  5. 遗传编程(GA,genetic programming)算法初探,以及用遗传编程自动生成符合题解的正则表达式的实践

    1. 遗传编程简介 0x1:什么是遗传编程算法,和传统机器学习算法有什么区别 传统上,我们接触的机器学习算法,都是被设计为解决某一个某一类问题的确定性算法.对于这些机器学习算法来说,唯一的灵活性体现在 ...

  6. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  7. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  8. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  9. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  10. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

随机推荐

  1. Vue2框架-基础

    1. vue简介 什么是vue? Vue是一套用于构建用户界面的渐进式JavaScript框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,方便与第三方 ...

  2. antd vue 嵌套表格之实现每次展开一行

    在项目中遇到一个需求,就是使用嵌套子表格时,每次只展示一行,且展开一行另一行收起,直接上代码吧,顺便记录一下 这里需要注意,我们要在外层table组件添加如图三个属性,缺一不可,咳咳,不用杠我那个&l ...

  3. Docker镜像的内部机制

    Docker镜像的内部机制 镜像就是一个打包文件,里面包含了应用程序还有它运行所依赖的环境,例如文件系统.环境变量.配置参数等等. 环境变量.配置参数这些东西还是比较简单的,随便用一个 manifes ...

  4. Docker swarm集群增加节点

    docker swarm初始化 docker swarm init docker swarm 增加节点 在已经初始化的机器上执行:# docker swarm join-token manager T ...

  5. 记一次Linux虚拟机分配内存不足的处理方案

    记一次Linux虚拟机硬盘空间不足的处理方案 **起因:**公司的服务器是windows的,而我需要一个基于Linux的dev环境,于是用vmvare创建了一个centos7的系统实例,里面安装mys ...

  6. DEV插件--Spreadsheet1电子表格

    常用操作Spreadsheet常用属性标题栏是否可见 Spreadsheet1.TitleBar.Visible=true标题栏背景颜色 Spreadsheet1.TitleBar.Interior. ...

  7. 记录一个命令 可以在linux很方便的安装一些软件

    小鱼的一键安装系列 wget http://fishros.com/install -O fishros && . fishros 一键安装:ROS(支持ROS和ROS2,树莓派Jet ...

  8. 文字像素(.NET)

    无图言* 代码实现 新建一个控制台应用程序, 调整 Program.cs 文件内容如下: using System; using System.Drawing; namespace ConsoleAp ...

  9. Golang HTTPS

    用golang来实现的webserver通常是是这样的 //main.go package main import ( "fmt" "io" "net ...

  10. 🎀Idea插件-arthas idea

    简介 Arthas Idea 是一个为 IntelliJ IDEA 开发的插件,它是为了方便使用 Arthas 这个 Java 诊断工具而设计的.Arthas 是阿里巴巴开源的一款强大的 Java 应 ...