description

定义一个字符串的子串是这个字符串的某个连续区间的字符组成的串。比如,“djq"的子串是"d”,“j”,“q”,“dj”,“jq”,和"djq"。

定义F(a,b)为最长在字符串bb中至少出现一次的字符串a的子串,例如:
F(“dmqdjx”,“jdmqdx”) =4 给定n个字符串s0,s1,…,sn−1和q组询问(xj,yj)
对于每组询问你需要求出F(sxj,syj).

输入格式
第一行两个正整数n,q.
接下来n行每行一个由小写字母组成的字符串表示si.
接下来q行每行两个数xj,yj表示一组询问。

输出格式
输出q行每行一个整数表示答案。

样例
输入样例1

3 3
probieren
birkerem
sadasment
0 1
1 2
0 2

输出样例1

3
1
2

输入样例2

10 20
aaabbbbbaa
babbaaaabb
aaaabaabba
abbabaaaaa
ababaababa
aabbbbbbba
bbabaaabba
baaaababaa
abaaaaabab
baabbbbabb
1 7
1 8
7 8
7 7
4 4
9 1
5 5
5 8
2 9
8 2
0 7
4 8
5 8
3 0
6 2
2 5
2 2
7 1
5 2
1 1

输出样例2

6
5
7
10
10
4
10
3
5
6
4
5
3
3
5
4
10
6
4
10

数据范围与提示
1≤n≤50000,1≤n≤100000,0≤xi,yi≤n−11\le n\le 50000,1\le n\le 100000,0\le x_i,y_i\le n-11≤n≤50000,1≤n≤100000,0≤xi​,yi​≤n−1

solution

非常原始的暴力:每一次都对yyy建后缀自动机,然后将xxx放上去匹配
肯定TTT,GG不用说

优化1: 每一次都重新建后缀自动机,着实太奢侈了
考虑将yyy排个序,相同的yyy就只建立一个后缀自动机,循环使用即可

优化2: 要知道后缀自动机匹配的时间就是xxx的长度
那么为了优化时间,每次就对长串建立后缀自动机,用短串去跑匹配

优化3: 记忆化!对于相同的xxx,没有必要做无用功

然后就这么AAA了!!时间复杂度O(nn)O(n\sqrt{n})O(nn​)


还有另外一种方法,不过俺没有写

code

#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 100005
struct SAM {int len, fa;int son[26];
}t[maxn];
struct node {int x, id;node(){}node( int X, int Id ) {x = X, id = Id;}
};
vector < node > query[maxn];
vector < int > G[maxn];
int n, Q, cnt, last;
char s[maxn];
int ans[maxn];void insert( int x ) {int pre = last, now = last = ++ cnt;t[now].len = t[pre].len + 1;while( pre && ! t[pre].son[x] ) t[pre].son[x] = now, pre = t[pre].fa;if( ! pre ) t[now].fa = 1;else {int u = t[pre].son[x];if( t[pre].len + 1 == t[u].len ) t[now].fa = u;else {int v = ++ cnt;t[v] = t[u];t[v].len = t[pre].len + 1;t[u].fa = t[now].fa = v;while( pre && t[pre].son[x] == u ) t[pre].son[x] = v, pre = t[pre].fa;}}
}bool cmp( node x, node y ) {return x.x < y.x;
}int solve( int u ) {int maxx = 0, len = 0, now = 1;for( int i = 0;i < G[u].size();i ++ ) {int v = G[u][i];while( t[now].fa && ! t[now].son[v] ) {now = t[now].fa;len = t[now].len;}if( t[now].son[v] ) {now = t[now].son[v];len ++;}maxx = max( maxx, len );}return maxx;
}int main() {scanf( "%d %d", &n, &Q );for( int i = 0;i < n;i ++ ) {scanf( "%s", s );int len = strlen( s );for( int j = 0;j < len;j ++ )G[i].push_back( s[j] - 'a' );}for( int i = 1, u, v;i <= Q;i ++ ) {scanf( "%d %d", &u, &v );if( G[u].size() < G[v].size() ) swap( u, v );query[u].push_back( node( v, i ) );}for( int i = 0;i < n;i ++ ) {memset( t, 0, sizeof( t ) );cnt = last = 1;for( int j = 0;j < G[i].size();j ++ )insert( G[i][j] );sort( query[i].begin(), query[i].end(), cmp );int siz = query[i].size();for( int j = 0;j < siz;j ++ ) {ans[query[i][j].id] = solve( query[i][j].x );while( j < siz - 1 && query[i][j].x == query[i][j + 1].x ) {ans[query[i][j + 1].id] = ans[query[i][j].id];j ++;}}}for( int i = 1;i <= Q;i ++ )printf( "%d\n", ans[i] );return 0;
}

【正睿2021寒假省选第二轮集训 day 1】串 (后缀自动机+记忆化)相关推荐

  1. 【正睿2021寒假省选第二轮集训 day 1】令牌生成 (组合数+二分)

    description solution 打表yyds 其实符合条件的个数跟nnn(非题目中的意思)有着等差数列公式的千丝万缕关系 所以可以二分出具体值 最后答案的取值范围一定是长成[,)[,)[,) ...

  2. 2021年NBA季后赛第二轮晋级预测

    2021年NBA季后赛第二轮晋级预测 1.西部球队晋级预测如下: 爵士VS快船,快船晋级. 太阳VS掘金,掘金晋级. 2.东部球队晋级预测如下: 篮网VS雄鹿,篮网晋级. 76人VS老鹰,76人晋级. ...

  3. 中国工程院2021年院士增选第二轮候选人名单公布

    来源:先进制造业 中国工程院2021年院士增选进入第二轮评审候选人名单 (按候选人姓名拼音排序) 未来智能实验室的主要工作包括:建立AI智能系统智商评测体系,开展世界人工智能智商评测:开展互联网(城市 ...

  4. 2021/9/12正睿10测Day.3

    半个小时左右大概看完了题,主要刚开始的时候吃了些东西. 这是第三次打正睿的十连,也是头一次在打正睿的十连遇到捆绑测试,对于我这种骗分狗来说首先心态上就很折磨,有些 subtask 只给了其中一两个量的 ...

  5. 省选模拟赛(正睿的最后一场)

    省选模拟赛(正睿的最后一场!!) 比赛时间安排 与正解的差距 T1 比赛时间安排 7.30-7.40 t1 能拿10分dfs,n=0的情况或许可以找规律 t2 看不懂 t3 暴力挺好写的,求lca太麻 ...

  6. 【第二轮征稿开启】ICRAIC 2021 机器人、自动化与智能控制国际会议诚邀您的参与!

    机器人.自动化与智能控制国际会议(ICRAIC 2021) 2021 International Conference on Robotics Automation and Intelligent C ...

  7. 重要!VALSE 2021确认参会及第二次【预注册】事宜的通知

    关注公众号,发现CV技术之美 文章来自VALSE. VALSE 2021大会 (http://valser.org/2021/)将于2021年10月8-10日在杭州举办,届时将延续历年传统,呈上8个大 ...

  8. .net 遍历数组找重复值写入一个新数组_第二轮 Python 刷题笔记一:数组

    经过四十多天缓慢的刷题,现在进度大概是刷了八十多道 LeetCode 题,最近也在吸取过来人的经验,仍然需要对刷题计划进行调整. 首先明确一下目标,我是有些 Python 基础,想通过刷题掌握更多算法 ...

  9. 【题解】CSP-J2021第二轮题解

    CSP-J2021第二轮题解 T1.分糖果 ⊗ \otimes ⊗ 简化题目:给定 l , r l,r l,r,求 max ⁡ i = l r ( i m o d n ) \max_{i=l}^{r} ...

最新文章

  1. 内存分配器设计的演进
  2. 商汤提基于贪心超网络的One-Shot NAS,达到最新SOTA | CVPR 2020
  3. 算法-------二分法查找
  4. 百度宣布AI语音调用登顶中国第一,自研芯片+最新端到端模型颠覆传统语音识别算法...
  5. 怎么显示全部背景图片_Windows 聚焦图片在锁屏界面和登陆界面没有显示
  6. server2019远程服务器ipv4地址_Windows Server 2019远程桌面服务配置和授权激活
  7. 将 ASP.NET Core 2.0 项目升级至 ASP.NET Core 2.1.3X
  8. jquery扩展 $.fn
  9. 08.C语言绘制系统界面
  10. Thinkphp5中session用法
  11. 2015级计算机科学与技术2班班级博客大全
  12. PX4 FMU启动流程 2. 二、 nsh_initscript
  13. 2022年最新配置:Eslint+Prettier+Volar
  14. 怎样清理苹果电脑磁盘空间_Mac启动磁盘已满?如何快速清理电脑磁盘
  15. qmake -v,出现错误:qmake: could not exec ‘/usr/lib/x86_64-linux-gnu/qt4/bin/qmake‘: No such file or direc
  16. android 提纲挈领
  17. 2019年北京市社会保险缴费明细表
  18. Open vSwitch安装指定版本ovs
  19. Python学习之列表--自动超市购物车
  20. 毕业设计记录-yolov5的wandb报错,原因和解决方法(非屏蔽wandb)

热门文章

  1. k8s 查看ip地址属于哪个pod_Kubernetes Pod 如何获取 IP 地址
  2. mysql 批量_mysql LOAD语句批量录入数据
  3. html5与课程思政,“课程思政”怎样做
  4. 华为交换机linux版本号,Cisco和华为交换机常用配置命令总结
  5. python调用robotframework_robotframework+python接口自动化的点滴记录(2)
  6. ubuntu mysql怎么备份_Ubuntu下MySQL备份与异地备份
  7. 怎么从转移特性曲线上看dibl_「科普向」这篇让你快速搞懂IGBT的静态特性
  8. 算法题目——质量(POJ-1862)
  9. java实用教程——组件及事件处理——布局的一个小实例
  10. 如何在MATLAB中把变量填到Word中,matlab数据写入现有excel表格-如何将matlab中变量写入excel...