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. js回忆录(5),终章

    无论走到哪里,都应该记住,过去都是假的,回忆是一条没有尽头的路,一切以往的春天都不复存在,就连那最坚韧而又狂乱的爱情归根结底也不过是一种转瞬即逝的现实. --马尔克斯 <百年孤独> 人生就 ...

  2. Nginx 之fastcgi常用配置项说明

    在LNMP环境中,我们都知道nginx如果要解析php脚本语言,就必须通过配置fastcgi模块来提供对php支持,那么在配置fastcgi的时候,关于fastcgi配置项的值应该怎么设置才能让其发挥 ...

  3. NumPy学习7

    今天学习了: 13, NumPy字符串处理函数 14, NumPy数学函数 15, NumPy算术运算 numpy_test7.py : import numpy as np ''' 13, NumP ...

  4. Qt/C++开发经验小技巧311-315

    关于流媒体推拉流延时的几点说明. 经常看到一些流媒体相关的程序,号称零延迟,不用怀疑,这肯定吹牛逼的. 搞音视频开发,有个核心的指标就是实时性,也就是延迟多少毫秒,这个问题问的也是最多的. 音视频文件 ...

  5. Lua程序设计笔记

    未学:第10章URL编码及以后的示例 13章位和字节 Lua语言基础 一组命令或表达式组成的序列叫chunk程序段,因为Lua语言可以被用作数据定义语言,chunk的大小没有限制,几MB的程序段也很常 ...

  6. k8s集群创建之后coredns一直处于pending状态

    按照官网教程 master节点kubectl init, 每个从节点kubectl join之后, 在master节点执行 kubectl get pods -n kube-system,发现core ...

  7. SLAM与AI的强强联合

    SLAM与AI的强强联合 本文默认大家已经熟知SLAM.导航.常见AI算法(比如深度学习.强化学习.卷积神经网络.监督学习)等基本概念,不熟的小伙伴可以从我已经出版的书籍<机器人SLAM导航核心 ...

  8. ubuntu 安装挂载mysql, redis和mongodb服务

    因为有两台电脑,所以准备把ubuntu电脑作成对外服务提供,各种数据库,中间件都使用docker安装管理,然后挂载配置和日志到本地,提供给另一台电脑的对外服务. 1. 安装docker sudo ap ...

  9. 🎀腾讯云nodejs SDK打包体积过大吐槽事件

    简介 2025年2月1日有位开发同学batchor在GitHub上提出了issue(你们是把***打包了吗?)对腾讯云Node.js的SDK打包体积过大进行吐槽(言语偏贴吧风格略显激进),SDK打包体 ...

  10. Cursor+playwright+mcp,好玩

    Cursor+playwright+mcp能干嘛,我就不多说,本文只讲怎么用上 第一步,安装下载Cursor.node.js,至于什么python环境,playwright网上一堆教程,自己查 第二步 ...