[CF 666E] Forensic Examination】的更多相关文章

CF 666E Forensic Examination 题意: 给出一个串\(s\)和\(n\)个串\(t_i\),\(q\)次询问,每次询问串\(s\)的子串\(s[p_l:p_r]\)在串\(t_l\)到\(t_r\)中哪个串中出现次数最多,以及出现次数最多的哪个串的下标 题解: 考虑把\(n\)个\(t\)串建出广义后缀自动机,然后后缀自动机上每个节点用动态开点线段树来维护每个\(t\)串能匹配到的数量,把每个\(t\)串的每个后缀能匹配的最长的串对应的后缀自动机上的点以当前\(t\)串…
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]…
题目:http://codeforces.com/contest/666/problem/E 对模式串建广义后缀自动机,询问的时候把询问子串对应到广义后缀自动机的节点上,就处理了“区间”询问. 还要处理模式串的区间,可以用线段树.给广义自动机的每个节点开一棵线段树存该节点代表的串在各模式串中的出现情况. 线段树合并到叶子时,直接把出现次数相加.这样会改值,所以如果不新建节点的话,父亲用的孩子的节点,父亲又要改值,在孩子上查询的时候就错了. 可以每次不是 ( !cr || !pr ) 的时候都新建…
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…