随笔分类 - 题解
摘要:题面 使用点分治的思想,对每个子树以中心为根dfs一遍算出 \(b,d\) 数组,然后把 \(a\) 数组(子树内所有点)按照 \(d\) 从小到大排序,用两个指针 \(l,r\) 扫数组。注意到这个题需要算个数,所以还需要考虑把在同一个子树内的删掉。另外开一个数组 \(c_i\) 动态维护 \([
阅读全文
摘要:题面 这个题相当于是把每个数的值作为 \(x_i\),在原序列中的位置为 \(y_i\),建出笛卡尔树,直接输出先序遍历(字典序最小)即可。 点击查看代码 #include<iostream> #include<cstdio> using namespace std; inline int rd()
阅读全文
摘要:题解 李超树维护直线,求单点最值。维护线段和直线的区别是,线段只是对一段区间有贡献,在线段树上这一段区间需要对应 \(O(\log n)\) 个节点,然后再往下传 \(O(\log n)\) 次,所以复杂度是两个 \(\log\) 的。直线只需要对整个区间进行这个操作,复杂度是 \(1\log\)。
阅读全文
摘要:题面 历史最值线段树。考虑到每个区间的操作大概是这样:先是一些加法操作,然后有一次赋值,在这次赋值之后所有的操作都可以表示成赋值。所以维护两类标记,一类表示前面的加法,另一类表示赋值,记录一下这个点有没有开始赋值即可。代码及其难调,建议理清思路再写…… 点击查看代码 #include<iostrea
阅读全文
摘要:题面 基本上所有树剖题都可以用LCT维护。两种思路,一种是直接暴力地维护每个点表示的区间的左右端点颜色和颜色段数,另一种是把连接同种颜色的边边权设为 \(0\),不同种颜色设为 \(1\),然后维护路径和即可。 一个注意的点在于LCT中的 \(tag\) 是对所有跟左右有关的值进行取反的标记。一定不
阅读全文
摘要:题面 对模式串建广义SAM,对于每个匹配串,首先求出 \(sl_i\) 表示以 \(i\) 为结尾的后缀的最长匹配长度。设 \(dp_i\) 表示 \(1\sim i\) 的最长匹配长度和,二分答案 \(mid\) 之后,有如下 dp 方程: \[ dp_i=\max(dp_{i-1},\max_{
阅读全文
摘要:题面 统计一个后缀和数组 \(suf_i\),其中 ) 为 \(1\),( 为 \(-1\),那么一个子串 \(s_{l,r}\) 是一个合法括号序列,当且仅当 \(\min_{l\leq k \leq r}suf_k\geq suf_{r+1}\),并且 \(suf_l=suf_{r+1}\)。
阅读全文
摘要:题面 把所有叶子拎起来当根,合并成一棵trie之后建广义 SAM(我直接每个叶子直接跑的,每次 \(lastpos\) 重置,也可过)。 点击查看代码 const int N=1e5+13,M=2e6+13; int n,m,nxt[M<<1],len[M<<1],ptot=1; std::vect
阅读全文
摘要:题面 对 \(n\) 个串建广义 SAM,每个点开一棵线段树维护 parent 树子树内的所有点都被哪些串走到过。这个直接线段树合并即可。注意分裂出来的点也需要update(我也不知道为何,反正不update会WA)。 点击查看代码 const int N=5e5+13,M=5e5+13,logN=
阅读全文
摘要:题面 虽然 \(n,m\leq 5000\),但是这题是 \(O((n+m)|\Sigma|)\) 的。首先建 \(S\) 的 SAM,拿 \(T\) 上去跑可以得到 \(T\) 每个前缀的匹配区间(在 \(S\) 中只出现一次)。接着建 \(T\) 的 SAM,也可以求出每个前缀在 \(T\) 中
阅读全文
摘要:题面 循环同构的话很容易想到把串延长一倍,跑的时候找所有长度为 \(n\) 的公共子串的出现次数即可。 点击查看代码 const int N=3e6+13; char s[N<<1]; int nxt[N<<1],len[N<<1],ptot=1,lastpos=1,cnt[N<<1]; std::
阅读全文
摘要:题面 对 \(T\) 建 SAM,拿 \(S\) 进去跑,可以得到每个 \(S\) 的前缀 \(S_i\) 的最长匹配后缀长度 \(sl_i\)。那么对于一个询问 \([l,r]\),答案就是 \(\max_{l\leq i\leq r}\{\min(sl_i,i-l+1)\}\)。 里面这个 \(
阅读全文
摘要:题面 本质不同第 \(k\) 小。对 SAM 上每个点求一个 \(b_i\) 表示从这个点开始往后走能走到的本质不同的子串个数。然后拿 \(k\) 在自动机上跑即可。 点击查看代码 const int N=9e4+13; char s[N]; int nxt[N<<1],len[N<<1],ptot
阅读全文
摘要:题面 拿出出现次数为 \(k\) 的点,给这个点表示的长度区间 \(+1\),这个可以使用差分解决。 点击查看代码 const int N=1e5+13; char s[N]; int nxt[N<<1],len[N<<1],ptot,lastpos,ind[N<<1]; ll cnt[N<<1],
阅读全文
摘要:题面 给一个串建 SAM,另一个串在上面跑。 点击查看代码 const int N=2.5e5+13; char s[N],t[N]; int nxt[N<<1],len[N<<1],ptot=1,lastpos=1; std::unordered_map<int,int> son[N<<1],bo
阅读全文
摘要:题面 每个点 \(u\) 代表 \(len_ u-len_{nxt_u}\) 这么多串。这个也可以 DAWG dp 求得,不过太麻烦了。 点击查看代码 const int N=1e5+13; int n,nxt[N<<1],len[N<<1],lastpos=1,ptot=1; char s[N];
阅读全文
摘要:题面 拆出来的点贡献为 \(0\),其他贡献为 \(1\),在 DAWG 上统计一个后缀和即可。 点击查看代码 const int N=1e6+13,M=26; int n,len[N<<1],nxt[N<<1],ptot=1,lastpos=1,ind[N<<1]; ll cnt[N<<1]; s
阅读全文
摘要:题面 当年见这题的时候还是初三的年轻选手。现在已经是老选手了…… 考虑推式子: \[ \begin{aligned} &\ \ \ \ \ \sum_T (\sum_{i=1}^{n-1}w_{e_i})\times\gcd_{i=1}^{n-1}w_{e_i}\\ &=\sum_T \big(\s
阅读全文
摘要:题面 板子。注意模数不是质数的 \(\det\): inline int det(int n){ int res=1;bool flag=0; for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j){ while(a[i][i]){ int tmp=a[j][i]
阅读全文
摘要:题面 这题挺有意思的。平常的矩阵树定理求的是 \[ \sum_T\prod_{e\in T}w_e \] 这题要求 \[ \begin{aligned} \sum_T\prod_{e\in T}p_e\prod_{e\not\in T}(1-p_e) &=\sum_T(\prod_{e\in T}p
阅读全文

浙公网安备 33010602011771号