Codeforces 666E Forensic Examination】的更多相关文章

E. Forensic Examination http://codeforces.com/problemset/problem/666/E 题目大意:给模式串S以及m个特殊串,q个询问,询问S的子串[pl,pr]在特殊串编号属于[l,r]中出现次数最多的次数以及在哪个特殊串. 一开始打算用S建SAM,特殊串去匹配...测样例时才想起这样不对.胡搞一番后,才开始写下面的做法. S与特殊串连在一起建SAM,记录S串[1,x]在SAM上节点位置,用来子串定位.每个节点的{right}该串出现的所有地…
题意:给定主串s和m个模式串,每次询问[l,r]的模式串中出现s[pl...pr]次数最多的串和次数. 这题挺简单的,先把所有模式串拿来建广义后缀自动机,询问相当于子树众数,用线段树合并即可. 那我为什么写这题题解呢? 1.作为我博客第一道非BZOJ题. 2.作为我博客第一道写题意(英文)的题. 3.这题是老师留的作业,所以可以骗访问量. 4.记录一下广义后缀自动机的优秀写法,以前我是无脑建的. #include <cstdio> #include <algorithm> usin…
题目链接 \(Description\) 给定串\(S\)和\(m\)个串\(T_i\).\(Q\)次询问,每次询问\(l,r,p_l,p_r\),求\(S[p_l\sim p_r]\)在\(T_l\sim T_r\)中的哪个串出现次数最多,输出最多次数以及它是\(T\)中的第几个.若最多的有多个,输出下标最小的. \(Solution\) 挺好的题吧 对\(T\)个串建SAM,然后要求出SAM每个节点上\(|right|\)最大的是哪个串. 每个节点的\(|right|\)可以在DFS par…
第一次做这种$SAM$带权值线段树合并的题 然而$zjq$神犇看完题一顿狂码就做出来了 $Orz$ 首先把所有串当成一个串建$SAM$ 我们对$SAM$上每个点 建一棵权值线段树 每个叶子节点表示一个匹配串能到达这个点的子串个数 这样我们对最后的$SAM$的权值线段树按$parent$树合并 询问的时候找到对应的$SAM$上的权值线段树直接查询就好了 具体的操作看代码吧~ #include<bits/stdc++.h> using namespace std; #define FO(x) {f…
传送门: 解题思路: 很坑的一道题,需要离线处理,假如只有一组询问,那么就可以直接将endpos集合直接累加输出就好了. 这里就要将询问挂在树节点上,在进行线段树合并时查询就好了. 代码超级容易写挂的. 注意要将匹配串时尽量找到最浅根,易于统计答案. 倍增处理就好了. 代码: #include<cstdio> #include<vector> #include<cstring> #include<algorithm> ; struct int_2{ int…
题意:给定字符串S,然后M个字符串T.Q次询问,每次给出(L,R,l,r),问S[l,r]在L到R这些T字符串中,在哪个串出现最多,以及次数. 思路:把所有串建立SAM,然后可以通过倍增走到[l,r]在SAM上的位置p,然后在这个位置p上求,求的过程就是一个线段树求区间最值. 现在的关键是得到线段树,这个线段树记录了endpos,这个可以用启发式合并. 注意现在是广义后缀自动机,不能用拓扑排序合并线段树. 必须用fail树DFS来合并. 不然会出错. 具体我也不知道,不过我估计是因为广义自动机里…
将所有串(包括S)放一块建SAM.对于询问,倍增定位出该子串所在节点,然后要查询的就是该子串在区间内的哪个字符串出现最多.可以线段树合并求出该节点在每个字符串中的出现次数. #include<bits/stdc++.h> using namespace std; #define ll long long #define N 1100010 char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c…
CF 666E Forensic Examination 题意: 给出一个串\(s\)和\(n\)个串\(t_i\),\(q\)次询问,每次询问串\(s\)的子串\(s[p_l:p_r]\)在串\(t_l\)到\(t_r\)中哪个串中出现次数最多,以及出现次数最多的哪个串的下标 题解: 考虑把\(n\)个\(t\)串建出广义后缀自动机,然后后缀自动机上每个节点用动态开点线段树来维护每个\(t\)串能匹配到的数量,把每个\(t\)串的每个后缀能匹配的最长的串对应的后缀自动机上的点以当前\(t\)串…
题目:http://codeforces.com/contest/666/problem/E 对模式串建广义后缀自动机,询问的时候把询问子串对应到广义后缀自动机的节点上,就处理了“区间”询问. 还要处理模式串的区间,可以用线段树.给广义自动机的每个节点开一棵线段树存该节点代表的串在各模式串中的出现情况. 线段树合并到叶子时,直接把出现次数相加.这样会改值,所以如果不新建节点的话,父亲用的孩子的节点,父亲又要改值,在孩子上查询的时候就错了. 可以每次不是 ( !cr || !pr ) 的时候都新建…
Description 传送门 Solution 对 \(T[1..m]\) 建立广义后缀自动机,离线,找出代表 \(S[pl,pr]\) 的每个节点,线段树合并. Code #include <cstdio> #include <vector> #include <cstring> #include <algorithm> const int N = 500005, M = 9500005; struct Edge { int v, nxt; } e[N]…
E - Forensic Examination 我也不知道为什么这个复杂度能过, 而且跑得还挺快, 数据比较水? 在sa上二分出上下界, 然后莫队 + 线段树维护区间众数. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int&g…
http://codeforces.com/problemset/problem/666/E (题目链接) 题意 给出一个主串$S$,$n$个匹配串编号从$1$到$n$.$m$组询问,每次询问主串的一个子串$S[p_l,p_r]$在编号为$[l,r]$的匹配串的哪一个中出现次数最多. Solution 首先我们把匹配串相连,中间用分隔符隔开,构建后缀自动机,并且给自动机主链上的节点打上标记,避免之后找后缀的时候重复计算. 每个节点与其对应$parent$相连,构建$parent$树.由于$par…
[CF666E]Forensic Examination 题意:给你一个字符串s和一个字符串集合$\{t_i\}$.有q个询问,每次给出$l,r,p_l,p_r$,问$s[p_l,p_r]$在$t_l...t_r$中的哪个字符串中出现的次数最多,以及最多次数是多少. $|s|\le 5\times 10^5,\sum |t_i|\le 5\times 10^4,q\le 5\times10^5$ 题解:我们对于$t_i$建立广义后缀自动机,并对于每个节点都维护:在它的right集合中,每个字符串…
E. Forensic Examination time limit per test:6 seconds memory limit per test:768 megabytes input:standard input output:standard output The country of Reberland is the archenemy of Berland. Recently the authorities of Berland arrested a Reberlandian sp…
[CF666E]Forensic Examination(后缀自动机,线段树合并) 题面 洛谷 CF 翻译: 给定一个串\(S\)和若干个串\(T_i\) 每次询问\(S[pl..pr]\)在\(T_l..T_r\)中出现的最多次数,以及出现次数最多的那个串的编号. 题解 好题啊. 我们对于所有的\(T\)串构建出广义后缀自动机之后 把\(S\)丢到\(SAM\)上匹配,对于每组询问, 相当于回答\(S[pl..pr]\)所代表的节点的\(right\)集合所代表的串的众数是哪个串,以及这个众数…
题意:给一个初始串s,和m个模式串,q次查询每次问你第l到第r个模式串中包含\(s_l-s_r\)子串的最大数量是多少 题解:把初始串和模式串用分隔符间隔然后建sam,我们需要找到在sam中表示\(s_l-s_r\)子串的状态节点(先找到\(s_r\)对应的节点,然后倍增parent树即可),我们需要找到包含\(s_l-s_r\)的模式串,这些节点肯定在parent树上位于我们找到的状态节点的子树上.那么我们按sam的topo序进行线段树合并,线段树区间表示l,r模式串中最大匹配值以及下标.每次…
洛谷 Codeforces 思路 最初的想法:后缀数组+区间众数,似乎并不能过. 既然后缀数组不行,那就按照套路建出广义SAM,然后把\(S\)放在上面跑,得到以每个点结尾会到SAM上哪个节点. 询问时对于\(p_r\)所在的节点,倍增往parent树上跳,找到包含\([p_l,p_r]\)的最小区间. 然后统计该节点\([l,r]\)的模式串中最多的是谁,用线段树合并实现. 好像就做完了? 特判 一般情况下,如果匹配到\(p_r\),那么\(S(p_l,p_r)\)一定时当前节点的祖先. 但有…
题目描述 给你一个串S以及一个字符串数组T[1..m],q次询问,每次问S的子串S[pl​..pr​]在T[l..r]中的哪个串里的出现次数最多,并输出出现次数. 如有多解输出最靠前的那一个. 题解 算是道字符串比较套路的题吧. 对模式串建SAM,对所有模式串的所有前缀维护right集合. 然后对于每个询问,倍增找到关键点,查子树众数. 坑:在最匹配串做匹配的时候,要记录匹配长度,如果匹配长度不够询问长度,直接判无解. 代码 #include<iostream> #include<cst…
思路 线段树合并+广义SAM 先把所有串都插入SAM中,然后用线段树合并维护right集合,对S匹配的同时离线询问,然后就好啦 代码 #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int MAXN = 100100; const int MAXlog = 20; char s[500500],t[50500]; int lens,m,q; name…
题解: 熟练掌握了后缀自动机后大部分题目应该都比较容易想 首先对t建立广义后缀自动机 然后我们可以用线段树合并处理出每个点每个串出现的次数,然后求出最大值 匹配的时候比较巧妙 我们离线处理 对于同一个ti,我们可以在parent树上倍增到最后一个满足l<=li的点 这个正确性是比较显然的,因为l-r和li-ri的出现次数是相同的…
题意 题目链接 Sol 神仙题Orz 后缀自动机 + 线段树合并 首先对所有的\(t_i\)建个广义后缀自动机,这样可以得到所有子串信息. 考虑把询问离线,然后把\(S\)拿到自动机上跑,同时维护一下最长能匹配的位置,对于每个以\(i\)位置为右端点的询问我们需要找到\(len\)最小的状态满足\(len[sta] >= pr - pl + 1\)(这部分把每个以\(i\)为端点的询问排序后暴力跳即可,复杂度\(O(n \sqrt{n})\)).那么现在的问题就是对于每个状态,如何知道他在每个\…
传送门 朴素想法:对\(M\)个匹配串\(T_1,...,T_M\)建立广义SAM,对于每一次询问,找到这个SAM上\(S[pl...pr]\)对应的状态,然后计算出对于每一个\(i \in [l,r]\),计算出\(T_i\)能够转移到这个状态的次数然后取\(max\). 需要解决两个问题: 1.如何快速找到\(S[pl...pr]\)在SAM上对应的状态. 因为题目没有给\(\sum pr - pl\)的条件,所以不能暴力,考虑一个一个字符加进去,每加入一个字符计算对应答案.将询问按照\(p…
题目描述 给出 $S$ 串和 $m$ 个 $T_i$ 串,$q$ 次询问,每次询问给出 $l$ .$r$ .$x$ .$y$ ,求 $S_{x...y}$ 在 $T_l,T_{l+1},...,T_r$ 中的哪一个里出现次数最多,输出出现次数最多的串编号(如果有多个则输出编号最小的)以及相应出现次数. $|S|,q\le 5\times 10^5$ ,$\sum\limits_{i=1}^m|T_i|\le 5\times 10^4$ . 题解 广义后缀自动机+树上倍增+线段树合并 对 $S$…
题意 给你一个串 $S$ 以及一个字符串数组 $T[1..m]$ , $q$ 次询问,每次问 $S$ 的子串 $S[p_l..p_r]$ 在 $T[l..r]$ 中的哪个串里的出现次数最多,并输出出现次数.如有多解输出最靠前的那一个. 题解 神仙题……虽然的确是好题……然而码量好大……好麻烦……因为一个sb错误调了一个下午 先膜一波zsy大佬……%%% 首先先把$T$给建出一个广义$SAM$.考虑每一个询问的$p_r$,如果在$SAM$上匹配到了一个节点,那么这个子串$S[p_l,p_r]$一定…
$ \color{#0066ff}{ 题目描述 }$ 给你一个串\(S\)以及一个字符串数组\(T[1..m]\),\(q\)次询问,每次问\(S\)的子串\(S[p_l..p_r]\)在\(T[l..r]\)中的哪个串里的出现次数最多,并输出出现次数. 如有多解输出最靠前的那一个. \(\color{#0066ff}{输入格式}\) 第一行一个个字符串表示\(S\) 第二行一个数字\(m\) 接下来\(m\)行每行一个字符串表示\(T[i]\) 接下来一行一个数字\(q\)表示询问次数 接下来…
题目 每天一道\(SAM\)真是非常开心 一看就是广义\(SAM\)+线段树合并了 我们存好\(S\)串每一个前缀的终点,之后在\(parent\)树上倍增找到表示\(S[l,r]\)这个子串的节点,我们用线段树合并维护好\(endpos\)集合,查一个区间最大值就好了 代码 #include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #define maxn 20000…
题面: 给你一个串S以及一个字符串数组T[1..m],q次询问,每次问S的子串S[p_l..p_r]在T[l..r]中的哪个串里的出现次数最多,并输出出现次数.如有多解输出最靠前的那一个. 分析: 第一次见这道题时,由于对算法十分陌生,就将其压进了任务计划,这一天又提到了这道题,这才算是重见天日. 数据结构题,越来越注重多种数据结构的搭配使用.搭配使用呢,我们就要知道各种数据结构的功能与适用范围,下面是这道题一个理想的思考过程(虽然我是抄的题解……) 首先,一个模式串的区间要在多个串上进行匹配,…
广义SAM专题的最后一题了……呼 题意: 给出一个长度为$n$的串$S$和$m$个串$T_{1\cdots m}$,给出$q$个询问$l,r,pl,pr$,询问$S[pl\cdots pr]$在$T_l\cdots T_r$中哪个串出现次数最多,出现了多少次. $1\leq n,q\leq 10^5,1\leq m,\sum|T|\leq 10^4$ 串中只会出现小写字母 题解: 神题啊……放图镇楼 先对T串建出广义SAM,然后把S放到上面匹配,求出每个字符所代表的节点,那么每次查询就相当于求这…
题意: 给定一个串 $S$ 和若干个串 $T_{i}$每次询问 $S[pl..pr]$ 在 $Tl..Tr$ 中出现的最多次数,以及出现次数最多的那个串的编号. 数据范围: 需要离线 题解:首先,很常规的对 $T_{1}$ 到 $T_{rmax}$ 的所有字符串构建一个广义后缀自动机.来一遍线段树合并,合并的权值是每个 $T$ 串出现的次数. 合并完毕后,再广义后缀自动机上的每个点的线段树上都能查到有哪些串能覆盖当前串. 把询问按照右端点排序,将 $S$ 匹配到广义后缀自动机当中,并通过倍增来将…
给你一个串S以及一个字符串数组T[1..m],q次询问,每次问S的子串S[pl..pr]在T[l..r]中的哪个串里的出现次数最多,并输出出现次数. 如有多解输出最靠前的那一个. 我们首先对m个字符串数组建出后缀自动机,然后我们可以通过跳trans边找到S前i个字符代表的前缀的最长后缀.我们要找的是S[pl..pr]并不是以pr结束最长的后缀,但我们可以确定S[pl..pr]一定是当前点的祖先所以当我们跳到pr代表的点时我们倍增往上跳知道找到一个点的长度刚好大于等于pr-pl+1,这个点就是询问…