一些题(十)

[JOISC 2017] 切符の手配

orz p_b_p_b

https://loj.ac/s/1353389

[P5163] WD与地图

倒着考虑,用线段树合并维护 SCC 内的点权。但是加入边 \((u,v)\) 时这两个点可能不会立即合并,需要求出 \(u,v\) 在同一个 SCC 时的最早时间。考虑整体二分,设当前二分到的时间区间为 \([L,R]\),询问边集为 \(A\)。那么需要将出现时刻 \(\le mid=(L+R)/2\) 的边加入跑 Tarjan,这样复杂度无法接受。考虑利用上一层 Tarjan 后的结果,具体地,只加入 \(A\)\(\le mid\) 的边并用可撤销并查集维护 SCC,然后保留缩成的 SCC 递归到 \((mid,R]\) 中(不需要保留 SCC 之间的连边,因为它们一定在递归下去的 \(A\) 里),然后再撤销并进入 \([L,mid]\)

https://www.luogu.com.cn/record/67335342

[BalticOI 2020] Viruses

考虑建出所有抗体的 AC 自动机,记 \(f_{k,i,j}\) 表示通过病毒 \(k\) 从自动机上 \(i\) 节点走到 \(j\) 节点,不经过代表抗体的节点的最小长度,如无法达到即为 \(\infty\)。那么一种突变方式 \(a\to\lang b_1b_2\ldots b_k\rang\) 就像相当于转移 \(f_a\gets f_a\oplus (f_{b_1}\otimes f_{b_2}\otimes \cdots\otimes f_{b_k})\),其中把 \(f\) 看作矩阵,\(\oplus,\otimes\)\((\min,+)\) 半环上的矩阵加法和乘法。通过引入一些中间变量会得到 \(O(G(\sum l)^2)\) 个变量和 \(O(G(\sum l)^3)\) 个形如 \(a\gets \min\{a,b+c\}\) 的转移。由于其中所有值都非负,可以用类似 dijkstra 的方法做,即每次取出最小的未被取出过的值,用它松弛有关它的所有转移。

[UR #23] 地铁规划

考虑用类似 baka trick 的方法:维护一个左栈一个右栈,当尺取的左端点移动的时候弹出左栈顶,然后移动右端点并往右栈添加元素,当左栈被弹完时将右栈倒过来作为新的左栈。但本题中只能在一个操作栈中进行操作,将其中属于左栈的元素称作 0 元素,右栈的称作 1 元素。于是当左端点右移时必须保证栈顶为 0 元素,考虑进行如下操作:设栈中有 \(cnt\) 个 0 元素,若 \(cnt=0\),则将栈全部弹出再倒着塞回,这样栈中全为 1 元素;否则,不停弹栈直到弹出 \(lowbit(cnt)\) 个 0 元素,然后先塞弹出的 1 元素,再塞 0 元素。这样就能满足要求。

考虑分析复杂度,对于一个元素,计在它底下(包含它)的 0 元素个数为 \(x\),那么:若它为 1 元素,它被撤回再插入时会有 \(x\gets x-lowbit(x)\),于是只会进行至多 \(\log n\) 次它便会变为 0 元素;否则,它被撤回再插入时必须满足 \(x\in [cnt-lowbit(cnt)+1,cnt]\),这样的 \(cnt\) 只有至多 \(\log n\) 个,由于 \(cnt\) 每次会 \(-1\),所以它至多会被操作 \(\log n\) 次。所以复杂度为 \(O(n\log n)\)

https://uoj.ac/submission/533456

[CF1610G] AmShZ Wins a Bet

调整可证每次删除的括号对一定是相邻的,那么最终删除的就是若干个合法括号子串。考虑从后往前 dp,设 \(f_i\) 表示第 \(i\) 个后缀的答案,那么有 \(f_i=\min\{S_i+f_{i+1},f_{i+len_i}\}\) 其中 \(len_i\)\(i\) 开始的最短非空合法括号串长度。考虑建出所有 \(f\) 及可能的转移反串的 trie,那么需要支持插入叶子和比较两个节点到根的串的字典序,这以用倍增维护哈希解决。

[AGC021F] Trinity

\(f_{i,j}\) 表示表格大小 \(i\times j\) 且每行至少有一个黑格的答案,那么枚举第 \(j+1\) 列新增了多少个有黑格的行可得到转移 \(f_{i,j}=\left(1+i+{i\choose 2}\right)f_{i,j-1}+\sum_{k<i}{i+2\choose k}f_{k,j-1}\),可以用卷积优化到 \(O(nm\log n)\)。最后答案即为 \(\sum_{i\le n}{n\choose i}f_{i,m}\)

[ARC058D] 文字列大好きいろはちゃん / Iroha Loves Strings

依次考虑每个字符串,维护可能成为答案前缀的串的集合 \(S\),它们肯定是某个串的若干个前缀。考虑加入一个串 \(t\),可以用 Z 函数 \(O(1)\) 比较两个 \(S\cup\{s+t\mid s\in S\}\) 中串的大小,然后用类似单调栈的东西构建出新的 \(S\)。注意判断每种前缀长度是否合法,即与后面的串一起能否凑成长度恰为 \(k\) 的串,可以倒着做背包解决。复杂度 \(O(nk)\)

[NEERC 2018] Distance Sum

随便找一棵生成树,那么只有 \(k=m-n+1\) 条非树边,考虑建出这些边端点的大小为 \(O(k)\) 的虚树。对于虚树上的点,\(O(n+m)\) 跑出它到所有点的最短路。考虑计算一个不在虚树上的点 \(u\) 到其它点的距离和:对于虚树上的点和完全不在虚树上的点是简单的;对于一条虚树边 \((x,y)\),可以通过 \(dis(x,u)\)\(dis(y,u)\)\(O(1)\) 算出 \(u\) 到这条边上所有点的距离和。复杂度 \(O((n+m)k)\)

https://codeforces.com/contest/1089/submission/147014182

[ARC133F] Random Transition

考虑有 \(n\) 个硬币,\(x\) 为正面朝上的硬币个数,那么每次操作相当于等概率的翻转一枚硬币。对每枚硬币写出它关于操作次数(\(x\),e.g.f)和是否为正面(\(y\))的二元生成函数,设 \(P=(y+1)e^x,Q=(y-1)e^{-x}\),那么初始为正面的硬币为 \(P+Q\),反面为 \(P-Q\)。于是所求即为 \([x^k/k!]\sum_i {A_i\over 10^9}(P+Q)^i(P-Q)^{n-i}\),一通推导后可变为 \(\sum_{i\le n} w_i(y-1)^i(y+1)^{n-i}\),可以用分治 NTT \(O(n\log^2 n)\) 求出。

[CF1470E] Strange Permutation

不同的操作序列一定对应不同的排列,并且对于两个最左操作不同的操作序列,它们可以直接比较字典序。想到维护一些序列 \(F_i\) 表示最左操作位置 \(\ge i\) 的最左操作的相对顺序,这样一次查询就可以通过至多 \(c\) 次二分得到答案。考虑从右向左来维护 \(F\),在加入 \(i\) 时,会插入至多 \(c\) 个操作,并且它们要么插入在 \(F_{i+1}\) 的左边,要么在右边。于是这个过程可以用 deque 来维护,且最终每个 \(F_i\) 都是 \(F_1\) 的一段子区间。时间复杂度 \(O(nc^2+qc\log(nc))\)

https://codeforces.com/contest/1470/submission/118765975

posted @ 2022-02-10 15:58  Y25t  阅读(225)  评论(0编辑  收藏  举报