thupc 2026 初赛 题解
除 C 外的代码位于文末。 补完了。
赛时通过 DFGIJLM。
会 DFGIJKLM。
不会 ABCEH。
吐槽:写 K 题的官方题解的人是不是没睡醒啊。怎么一堆字母写错的啊。😓
A
考虑分治。
一种是“猫树分治”。或者说,当分治到 \([l,r]\) 时,对有 \(mid\in [ql,qr]\) 的询问进行求值。但是这里不太好做。
还有一种类似线段树的想法,要求子问题是可合并的,也就是当分治到 \([l,r]\) 时,对 \([l,r]\subseteq [ql,qr]\) 的询问进行求值,然后把这些段合并起来。
第一种分治方式,因为不太好做动态加入,所以如果加入完,在查询的时候多一个 序列位置的限制,那么基本无法单 log。
因为子问题是可合并的,并且一定是包含了整个区间,所以不需要 序列位置的限制。
显然考虑虚树,首先有一个 \(O(1)\) LCA,然后区间内按照 dfn 排序可以在分治的时候顺便做了。
对于一次询问,我们不想再去找距离虚树最近的位置,所以直接把询问点也拿去建虚树。
所以可以 \(O(n+q)\) 建出虚树。
令 \(sz_x\) 表示 \(x\) 子树内在 \(a_{[l,r]}\) 内的点的个数。
对于询问的点 \(u\),如果 \(sz_u\neq 0\),那么 \(ans\gets u\)。
然后考虑 \(u\) 的祖先,这里通过判定 \(sz_x\) 和 \(sz_i\) 是否相等从上到下递推答案,可以一次 dfs 解决。
复杂度 \(O(n\log n)\)。
B
border 长度为 \(k\),意味着 \(s\) 的前后 \(k\) 个是相同的。
因为 \(q\) 很小,所以考虑一个每次 \(O(n)\) 的做法。
比较牛的想法是,因为一次查询中心是不变的,同时 border 对应的前后两个串到中心的距离是相同的,所以考虑把这两个位置做操作合到一个位置。
一个比较好的方式是,提取出以 \(\frac{k}{2}\) 为中心的极长子串 \(s\),令 \(t=s_1s_ns_2s_{n-1}\cdots s_ns_1\)。即把 \(s\) 和 \(s\) 逆序分别放在奇偶位。
然后后面就随便观察一下,发现 border 会在 \(t\) 的中心点之前的某个偶回文串被统计到。
使用 manacher 即可 \(O(n)\) 求出回文串个数。
C
很厉害。
想题的时候知道要先证明下界是 \(2n-2\),但是不会。于是做不出来。
证明考虑分类讨论。
首先比较容易的观察是,我们可以把 \(1\times k(k\times 1)\) 的矩形对应到其所在的行(列)上的唯一黑格子。显然一个矩形会恰好对应一个黑格子。
注意 \(1\times 1\) 要么对应到行,要么对应到列。
考虑对黑格子对应的矩形个数讨论。
- 存在黑格子没有被矩形对应
- \([A]\) 存在一个黑格子没有被矩形对应。此时可以发现黑格子同行同列的格子一定是被矩形垂直(垂直于行/列)穿过的,所以至少有 \(2n-2\) 个矩形。
- 存在多个黑格子没有被对应,观察不同黑格子行列的交点,显然交点至少会对应一个,所以不成立。
- 所有黑格子都有对应
- 存在不超过一个黑格子只有一个对应矩形。此时矩形个数 \(\geq 2n-1\)。
- \([B]\) 存在两个黑格子只有一个对应矩形。此时矩形个数 \(\geq 2n-2\)。
- 存在三个(及以上)黑格子只有一个对应矩形。同样观察不同黑格子行列的交点,显然矛盾。
所以得证。
然后根据证明,我们只关心 \([A][B]\) 两个情况。
对于 \([B]\),我们考虑构造 \(2n-2\),(此处建议阅读官方题解)发现中间的部分已经确定了,只关心两个点左上左下右上右下四个方向。
对于 \([A]\) 同理。
所以考虑处理左下的答案。其他方向同理。
注意到,如果左下存在两个互不偏序的黑格子,则不可能。
否则我们直接从第一个偏序的黑格子转移过来。方案数组合数随便算。
比较有意思的是 \(O(n)\) 判定是否存在两个互不偏序的黑格子。
这里官方题解比较唐。考虑对 \(i\) 这一维扫描,对 \(a_i\) 单调栈求出 \(pre1_i\),对 \(a_i\) 扫描,对 \(i\) 做单调栈求出 \(pre2_i\),如果 \(pre1_i\neq pre2_i\) 则不合法。否则合法。
复杂度线性。
D
网络流集合划分板子。
不会的建议左转 更板子的板子。
E
\(n\leq 11\),直接贝尔数暴搜预处理所有等价串的模式,在 \(n=11\) 的时候也只有 \(B_{11}=678570\) 种。在查询的时候,二分答案即可。
\(n\geq 12\),考虑答案最小的串 \(s\),那么 \(s\) 中至少出现了 \(12\) 种字符。所以和 \(s\) 等价的个数一定 \(\geq A_{26}^{12}>10^{15}\)。
所以只要输出 \(s\) 即可。
考虑怎么构造这样的 \(s\)。
首先要知道,所谓“最大生成树”的权值,其实可以看作是 \(\sum \operatorname{lcp}(sa_i,sa_{i+1})\)。
考虑这时候,如果 \(s\) 的子串 \(t\) 出现了 \(k\) 次,那么就会被贡献 \(k-1\) 次。
换句话说,我们要让 \(s\) 的不同子串数尽可能多。
首先考虑,如果 \(s\) 中长度为 \(k\) 的子串互不相同,那么长 \(k+1\) 的一定也互不相同。
所以我们贪心的从 \(k=1\) 开始构造 “长度为 \(k\) 的子串互不相同” 的串。
考虑一个叫做 De Bruijn 序列的东西。
首先先学会做 CSES1692。
发现要求的就是这种东西(的 \(26\) 进制版本)。
\(k=1\) 当然就是 \(s=\texttt{a\dots z}\)。
然后迭代这个串,对于 \(k+1\) 的情况,相当于已经沿着 \(s\) 走了一段距离,所以 ban 掉这些边即可。
对于 \(k\geq 2\),所有长度为 \(k\) 的子串互不相同,使用上面那题的做法,跑欧拉回路,复杂度 \(O(26^k)\)。
注意到 \(k=4\) 时序列长 \(26^4>4\times 10^5\)。所以 \(k\leq 4\),复杂度可以接受。
预处理 \(s\) 后,只要输出 \(s\) 长度为 \(n\) 的前缀即可,根据贪心构造,显然是最优的。
F
发现 \(n\leq 10^{18}\) 的时候,树高 \(h\leq 9\)。
然后通过一些数学,可以求出父亲节点和子树大小。
然后按位考虑。
在更新一个节点 \(x\) 的子树为 \(1\) 的时候,根据子树大小奇偶性,可以直接跳没有操作过的父亲更新维护的答案。
在查询的时候,一种是祖先有操作过,那么答案只和子树大小奇偶性有关,否则就和当前节点维护的答案有关。
复杂度 \(O(nh\log V)\)。
G
首先第一个串的串首一定是第一个 \(1\),设位于 \(p\)。然后枚举第二个串的串首位于 \(q\)。
然后通过一些尝试,猜测,答案一定形如:第一个串一定是 \([p,q)\) 之间的 \(1\) 构成的串,第二个串是 \(q\) 之后的字符构成的串。
然后没拍出来锅,说明是对的。😓
H
好难。
首先我们先不关心内部每个人的大小关系,先把所有的 \(c\) 排序,排序后我们可以得到 \(c_1</=c_2</=\cdots</=c_m\),一共有 \(2^{m-1}\) 种可能。
设 \(c_1,c_2,\cdots,c_n\) 相邻的偏序关系是 \(M\),则:
- 设 \(F(M)\) 表示满足偏序关系 \(M\) 的 \(c\) 的多重组合数之和 \(\sum_c\binom{n}{c_1,c_2,\cdots,c_m}\)。
- 设 \(W(M)\) 表示给 \(c\) 填上原编号后,权值的和。注意 \(F(M)\) 已经把相等的 \(c\) 的编号重排给算上了,所以这里应该看作是,给每个人一个 \(c_i\) 的方案的权值之和。\(c_i\) 的值相同则算同一方案。
先考虑 \(F(M)\) 的求法。
考虑 \(n\) 很大,并且 \(p\) 是小质数,所以考虑 Lucas。
考虑 Lucas 定理,可以得到性质:如果多重组合数 \(\binom{n}{S}\neq 0\),则对于 \(p\) 进制下的每一位 \(x\)(设值为 \(v_p(x)\)),都有 \(\sum_{i\in S}i_p(x)\leq n_p(x)\)。
所以除了偏序关系外,可以按位考虑。
对于偏序关系,如果上面的位已经有 \(c_i<c_{i+1}\) 了,那么下面的位对 \(c_i,c_{i+1}\) 的关系没有限制。
否则 \(c_i=c_{i+1}\),则对于第 \(d\) 位有 \(c_i(d)\leq c_{i+1}(d)\)。
位之间只有偏序关系的影响传递,相对独立,所以考虑 dp。
一种想法是考虑枚举最后的 \(c\) 的关系 \(M\),然后再从上到下 dp,记录相邻位的限制。但是这样做复杂度包括转移不太能优化。
考虑枚举最后的 \(c\) 其实是比较麻烦的,所以直接 dp 记录 \(c\) 的关系。
因为高位影响低位,所以可以在 dp 的过程中记录高位 \(c\) 的关系。显然关系一定是 \(c_i</=c_{i+1}\)。所以此时 dp 的状态是 \(2^{m-1}\) 的。
可以简单设出 dp 状态 \(f(d,M)\) 表示 dp 到第 \(d\) 位,当前偏序关系是 \(M\) 的方案数。
考虑转移的时候形如 \(f(d,M)g(M,M',n_p(d))\to f(d-1,M')\)。
发现位之间的转移形如一个枚举子集,位内的转移形如一个背包(卷积)。
考虑已知 \(M,M'\),预处理 \(g(M,M',*)\)。
首先观察到 \(M\) 中 \(<\) 的关系,意味着高位已经决定,所以此时当前 \(<\) 两侧是无关的,所以可以拆成子问题,然后最后卷积合并回来。
于是考虑 \(|M|=k\),\(M\) 中全是 \(=\) 的情况。
考虑预处理全是等号的 \(M\) 到 \(M'\) 的转移。
同样 dp。设 \(h(i,s,S,lst)\) 表示 dp 到 \(i\),和是 \(s\),\(M'=S\),第 \(i\) 个数是 \(lst\) 的方案数。但是转移还要枚举 \(v\),复杂度太高了。
注意到 \(c\) 是单调的,所以考虑完全背包的思路。
也就是 \(h(i,s,S,lst)\to h(i,s,S,lst+1)\) 表示 \(lst\) 没选中。
否则有 \(h(i,s,S,lst)\to h2(i+1,s+lst,S,lst)\) 表示第一次选中 \(lst\)。
以及 \(h2(i,s,S,lst)\to h2(i+1,s+lst,S',lst)\) 表示多次选中 \(lst\)。这里 \(S'\) 自己算。
最后把 \(lst\) 扔掉,有用的是每个 \(s,S\) 的最后一个状态 \(h(k,s,S,p-1)\)。
注意到对于 \(k\),只有 \(2^k\) 种 \(S\),所以预处理 \(h\) 是 \(\mathcal{O}(2^mp^2)\) 的。
一次卷积合并是 \(\mathcal{O}(p^2)\) 的,所以复杂度大约是 \(\mathcal{O}(3^m\times mp^2)\) 的,在 \(m=12\) 的时候,看起来能不能过啊。
需要注意到,其实对于 \(M\) 中使用 \(<\) 连接的等号连续段,相对位置无关。
所以 \(M\) 其实看做是一个拆分。
此时只计算每种拆分的一个代表元 \(M_0\),对于拆分相同的其他 \(M\),发现转移直接从 \(M_0\) 的转移改改就好了。
以及 \(M'\) 按照 \(M\) 的段进行拆分后,如果多重集相同也可以只选一个计算。
这样发现 \(m=12\) 的时候,只有 \(\mathcal{A}(12)=17547\) 种需要计算的转移,显然其远小于 \(3^{11}\),并且因为 \(m\) 因子和 \(M'\) 比 \(M\) 多的 \(<\) 的个数有关,所以 \(m\) 因子完全跑不满,卷积带一个 \(\frac{1}{2}\) 的常数,故 \(\mathcal{O}(\mathcal{A}(m)mp^2)\) 是可以接受的。
当然这里还可以优化一下,注意到这里 \(M'\) 可以按照 \(M\) 的等号连续段分割,dfs 搜出所有的可能性,所以在 dfs 的时候顺便做卷积。这样应该是 \(\mathcal{O}(\mathcal{A}(m)p^2)\) 的(?
到这里,我们已经处理出 \(F(M)\) 了。
然后是 \(W(M)\)。
这是相对简单的。
预处理 \(A(S,T)\) 表示 \(\prod_{i\in S}\prod_{j\in T}a(i,j)\),\(B(S)=\prod_{i,j\in S,i\neq j}b(i,j)\)。
然后 dp \(v(j,S)\) 记录当前确定 \(M=j\),选择了 \(S\) 中的编号的权值和。
转移就是枚举下一个等号连续段。
注意到整个 dp 可以看作是枚举子集的子集的子集,所以复杂度 \(\mathcal{O}(4^m)\)。
于是 \(W(M)=v(M,U)\)。
最后是回答询问。沿着子集转移即可。复杂度 \(\mathcal{O}(q\log_p V 3^m)\)。
所以总复杂度 \(\mathcal{O}(2^mp^2+\mathcal{A}(m)p^2+q\log_p V 3^m)\)。
I
感觉挺套路的。
首先第一问通过贪心求得。
第二问,按位考虑。注意到比较大小的时候,如果高位不同,那么和低位无关。
所以从高到低考虑。按位的独立性引导我们思考 dp。所以考虑区间 dp \(f(k,l,r)\) 表示当前 dp 区间 \([l,r]\),在决策第 \(k\) 位的方案数。
然后枚举第 \(k\) 位为 \(1\) 的第一个位置 \(t\),有 \(f(k,l,r)=\sum f(k-1,l,t-1)f(k-1,t,r)\)。
复杂度 \(O(n^3m)\)。区间 dp 常数小所以可以通过。
J
感受那股劲。😓
因为是 \(\prod=2^{2t+1}\),所以每项一定都是 \(2\) 的次幂。
首先排除 \(n\) 是偶数。
然后考虑观察一下。发现 \(m=2^{2k+1}\) 一定不行。也就是不能出现 \(2^{2k+1}\)。
考虑拓展这个条件。考虑从 \(m\) 左右两侧构造。
令 \(f(x)\) 表示 \(x\) 离最靠近 \(x\) 的比 \(x\) 大的 \(2\) 的幂的距离。
那么左右一定是 \(2^y-m\) 类型的。一个粗略的想法是,对 \(2^y-m\) 继续思考,发现如果一直操作,能到达 \(2^{2k+1}\),那么稍微想一下就发现一定是不合法的。
我们感受一下,发现一定存在 \(a\) 的一个循环同构使得 \(a_1=a_n\)。
思考下,考虑 \(a_i\to a_{i+1}\),要么 \(a_{i+1}>a_i,f(a_{i+1})=a_i\),要么 \(f(a_i)=a_{i+1}<a_i\)。
注意到 \(a_{i+1}>a_i\) 最后一定会回到 \(a_i\),\(f(a_i)=a_{i+1}<a_i\) 是唯一的。
所以我们一直向 \(f(a_i)\) 迭代直到变为 \(2\) 的幂。然后判定是否是 \(2^{2k+1}\),是则不合法。否则合法。
K
可以让答案变小的方式,就是选择 \(A\cap B\) 中的数。
设 \(P\subseteq A,Q\subseteq B\) 是最后选择的数。
对于 \(P\cap Q\) 中相邻的两个 \(x,y\),其间的 \(A,B\) 中的选择是独立的。
根据独立性,我们对着这个 dp。
设 \(f(i)\) 表示选择到了 \(i\in P\cap Q\) 的最小代价。
然后考虑转移。有 \(f(i)+dis_A(i,j)+dis_B(i,j)\to f(j)\)。
其中 \(dis_A,dis_B\) 表示独立贪心从 \(i\) 选择到 \(j\) 的最小代价。
I.
然后考虑分步转移。也就是令 \(g(i,j)\) 表示当前 \(A\) 选到 \(i\),\(B\) 选到 \(j\) 的代价。
然后在 \(\min(i,j)\) 处转移,挑较小的那个位置进行贪心转移。
此时的状态数仍然不可接受。
问题在于,假设 \(i<j\),则有很多个 \(j\) 要进行转移。考虑一个剪枝:
如果对于 \(j_1<j_2,g(i,j_1)\geq g(i,j_2)\),则 \(g(i,j_1)\) 被偏序,不需要继续转移。
加上这个剪枝之后。我们发现状态数锐减到 \(O(n)\)。使用你喜欢的方式维护状态就可以通过。
考虑证明,不妨假设 \(i<j\)。如果存在 \(j_1<j_2<j_3\) 使得 \(g(i,j_1)<g(i,j_2)<g(i,j_3)\),根据转移的性质,有 \(nxt_{j_1}>j_3\),所以 \(g(i,j_1)\) 的上一个状态一定会以 \(\leq 1\) 的代价转移到 \(g(i,j_3)\) 的上一个状态。即 \(g(i,j_3)\) 不是最优的。故矛盾。
II.
这应该是更自然的做法。
比较自然的,我们会想到 \(dis_A(x,y)\approx dep_A(x)-dep_A(y)\),其中 \(dep_A(x)\) 是 \(x\) 贪心移动到 \(L\) 的最小步数。
具体地,我们设 \(\epsilon(x,y)=dis_A(x,y)-(dep_A(x)-dep_A(y))\),那么有 \(\epsilon(x,y)\in [0,1]\)。
考虑把贪心跳的过程建成树,注意到 \(\epsilon(x,y)\) 其实就是判断 \(y\) 是不是 \(x\) 的祖先。即 \(\epsilon(x,y)=[y{\red{\not\in}} anc(x)]\)。
接下来一步反正我没意识到。。
然后考虑使用 dfn 判定:dfs 到 \(u\) 时,按照子节点编号从小到大访问,那么有 \(\epsilon(x,y)=[dfn_x<dfn_y]\)。
当然这样做的正确性显然。
然后就是考虑 dp。如果是直接做三维偏序,使用 CDQ 分治可以做 \(O(n\log^2 n)\)。
但是仍然存在更优秀的做法。
注意到一次转移,dp 值只会变化 \([-1,1]\)。所以转移只会从前缀的 \(\min,\min+1\) 这两个值来。
所以我们枚举前驱 \(x\) 的值,使用线段树维护所有 \((dfn_A(x),dfn_B(x))\),每次相当于查询是否存在偏序某对 \((u,v)\) 的状态。
因为是存在性,所以线段树下标维护 \(dfn_A\),值维护 \(\max dfn_B(x)\)。
复杂度 \(O(n\log n)\)。
L
首先公式的意义是 \(\sum_i(\text{avg }S_i)^2\)。所以如果 \(S_i,S_j\) 值域有交一定不优。所以看作是在排序后的 \(a\) 上做切分。
考虑若组数确定,那么一定是贪心地让切分点尽可能变大。因为一个切分位置向小的方向移动,两侧的 \(\text{avg }S\) 都会变小。
然后是组数的问题。发现组数一定越多越好。
然后考虑构造方案。
首先前面一定是一堆 \(|S|=l\) 的,后面一定是一些 \(|S|=r\) 的,中间会有一个 \(|S|\in [l,r]\) 的。
因为组数已知,所以左右两部分的个数和中间的大小都可以算出来。
然后考虑快速计算,预处理长为 \(d\) 的作为 \(l\) 的切分的前缀贡献,以及作为 \(r\) 的后缀贡献。
然后需要预处理的量级就是调和级数 \(O(n\log n)\) 的。
M
用回你那土豆 OJ 吧。比 M 还搞笑的是 OJ。😓😓😓
\(\texttt{\red{runtime\ error:}}\texttt{\ load\ of\ null\ pointer\ of\ type\ "D"}\)
Code
A
\(O(n\log n)\)。
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 5e5 + 5;
int n;
int dfn[N], dep[N], fa[N], ts;
template<typename T, int N>
struct ST {
static const int K = __lg(N) + 1;
int n;
T st[K][N];
T (*op)(T, T);
ST() { op = [](T x, T y) { return min(x, y); }; }
ST(T (*_op)(T, T)) { op = _op; }
void init(int _n, T *a = NULL)
{
n = _n;
if(a != NULL) for(int i = 1; i <= n; i ++) st[0][i] = a[i];
for(int j = 1; j < K; j ++)
for(int i = 1; i <= n; i ++)
st[j][i] = op(st[j - 1][i], st[j - 1][min(n, i + (1 << j - 1))]);
}
T qry(int l, int r)
{
int h = __lg(r - l + 1);
return op(st[h][l], st[h][r - (1 << h) + 1]);
}
} ;
ST<int, N> st([](int x, int y) { return dep[x] < dep[y] ? x : y; });
inline int lca(int x, int y)
{
if(x == y) return x;
x = dfn[x], y = dfn[y];
if(x > y) swap(x, y);
return fa[st.qry(x + 1, y)];
}
struct vec {
int fst[N], nxt[N * 2], h = 2; int to[N * 2];
void add(int x, int y) { nxt[h] = fst[x], fst[x] = h, to[h] = y, h ++; }
} e, e2;
void dfs1(int x, int fa)
{
::fa[x] = fa;
dfn[x] = ++ts;
dep[x] = dep[fa] + 1;
for(int ii = e.fst[x], i = e.to[ii]; ii; ii = e.nxt[ii], i = e.to[ii])
{
if(i == fa) continue;
dfs1(i, x);
}
}
int sz[N], f[N];
void dfs2(int x, int fa)
{
for(int ii = e2.fst[x]; ii; ii = e2.nxt[ii])
{
int i = e2.to[ii];
if(i == fa) continue;
dfs2(i, x);
sz[x] += sz[i];
}
}
void dfs3(int x, int fa)
{
for(int ii = e2.fst[x]; ii; ii = e2.nxt[ii])
{
int i = e2.to[ii];
if(i == fa) continue;
f[i] = f[x];
if(sz[i] < sz[x]) chmax(f[i], x);
dfs3(i, x);
}
}
int pl[N], pr[N], a[N], u[N], ans[N];
auto comp = [](int x, int y) { return dfn[x] < dfn[y]; };
int stk[N], sh;
void buildvt(const vector<int>& v)
{
sh = 0; stk[++sh] = 1;
e2.h = 2;
e2.fst[1] = 0; sz[1] = f[1] = 0;
for(int i : v)
{
if(i == 1) continue;
int lc = lca(stk[sh], i);
if(lc != stk[sh])
{
while(dfn[stk[sh - 1]] > dfn[lc])
{
e2.add(stk[sh - 1], stk[sh]);
sh --;
}
if(stk[sh - 1] != lc)
{
e2.fst[lc] = 0; sz[lc] = f[lc] = 0;
e2.add(lc, stk[sh]);
stk[sh] = lc;
}
else e2.add(lc, stk[sh]), sh --;
}
e2.fst[i] = 0; sz[i] = f[i] = 0;
stk[++sh] = i;
}
for(int i = 1; i < sh; i ++) e2.add(stk[i], stk[i + 1]);
}
int id[N];
void solve(int l, int r, const vector<int>& q)
{
int mid = l + r >> 1;
vector<int> ql, qr, qm;
for(int i : q)
{
if(pl[i] <= l && pr[i] >= r) qm.emplace_back(i);
else
{
if(pr[i] > mid) qr.emplace_back(i);
if(pl[i] <= mid) ql.emplace_back(i);
}
}
if(l != r)
{
solve(l, mid, ql), solve(mid + 1, r, qr);
inplace_merge(id + l, id + mid + 1, id + r + 1, comp);
}
else id[l] = a[l];
vector<int> qu(qm); for(int &i : qu) i = u[i];
vector<int> uu(id + l, id + r + 1);
vector<int> s(uu.size() + qu.size());
merge(uu.begin(), uu.end(), qu.begin(), qu.end(), s.begin(), comp);
s.erase(unique(s.begin(), s.end()), s.end());
buildvt(s);
rep(i, l, r) sz[a[i]] = 1;
dfs2(1, 0);
dfs3(1, 0);
for(int i : qm) chmax(ans[i], f[u[i]]);
for(int i : qm) if(sz[u[i]]) chmax(ans[i], u[i]);
}
int q, m;
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> m >> q;
rep(i, 1, n - 1)
{
int x, y; cin >> x >> y;
e.add(x, y); e.add(y, x);
}
dfs1(1, 0);
rep(i, 1, n) st.st[0][dfn[i]] = i;
st.init(n);
rep(i, 1, m) cin >> a[i];
vector<int> qq;
rep(i, 1, q) cin >> pl[i] >> pr[i] >> u[i], qq.emplace_back(i);
sort(qq.begin(), qq.end(), [](int x, int y) { return dfn[u[x]] < dfn[u[y]]; });
solve(1, m, qq);
rep(i, 1, q) cout << ans[i] << "\n";
return 0;
}
\(O(n\log^3 n)\),谨慎阅读,,
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 5e5 + 5;
struct BIT {
int a[N];
void upd(int q, int v) { for(int i = q; i < N; i += (i & -i)) a[i] += v; }
int qry(int q) { int ans = 0; for(int i = q; i; i -= (i & -i)) ans += a[i]; return ans; }
int qry(int ql, int qr) { return qry(qr) - qry(ql - 1); }
} t2;
struct BIT2 {
vector<int> a; int N;
void init(int _N) { N = _N; a.assign(N, 0); }
void upd(int q, int v) { for(int i = q; i < N; i += (i & -i)) chmax(a[i], v); }
void clr(int q) { for(int i = q; i < N; i += (i & -i)) a[i] = 0; }
int qry(int q) { int ans = 0; for(int i = q; i; i -= (i & -i)) chmax(ans, a[i]); return ans; }
} t[N];
int n;
int dfn[N], dep[N], sz[N], top[N], fa[N], son[N], ts;
struct vec {
int fst[N], nxt[N * 10], h = 2; int to[N * 10];
void add(int x, int y) { nxt[h] = fst[x], fst[x] = h, to[h] = y, h ++; }
} e;
void dfs1(int x, int fa)
{
::fa[x] = fa;
sz[x] = 1;
dep[x] = dep[fa] + 1;
for(int ii = e.fst[x], i = e.to[ii]; ii; ii = e.nxt[ii], i = e.to[ii])
{
if(i == fa) continue;
dfs1(i, x);
sz[x] += sz[i];
if(sz[i] > sz[son[x]])
son[x] = i;
}
}
int td[N];
void dfs2(int x, int tp)
{
td[x] = x == tp ? 1 : td[fa[x]] + 1;
t[tp].N ++;
top[x] = tp;
dfn[x] = ++ts;
if(son[x]) dfs2(son[x], tp);
for(int ii = e.fst[x], i = e.to[ii]; ii; ii = e.nxt[ii], i = e.to[ii])
if(i != fa[x] && i != son[x])
dfs2(i, i);
}
int w[N];
void upd(int x, int z)
{
t2.upd(dfn[x], z);
t[top[x]].upd(td[x], x);
while(x)
{
x = fa[top[x]];
if(x) t[top[x]].upd(td[x], x);
}
}
void clr(int x)
{
t2.upd(dfn[x], -1);
t[top[x]].clr(td[x]);
while(x)
{
x = fa[top[x]];
if(x) t[top[x]].clr(td[x]);
}
}
int qry(int x)
{
int ans = 0;
if(t2.qry(dfn[x], dfn[x] + sz[x] - 1))
chmax(ans, x);
while(x)
{
if(x != top[x])
chmax(ans, t[top[x]].qry(td[x] - 1));
int ls = top[x];
x = fa[top[x]];
if(x && t2.qry(dfn[x], dfn[x] + sz[x] - 1) - t2.qry(dfn[ls], dfn[ls] + sz[ls] - 1))
chmax(ans, x);
}
return ans;
}
int pl[N], pr[N], a[N], u[N], ans[N];
vector<int> ul[N], ur[N];
void solve(int l, int r, const vector<int>& q)
{
if(l == r)
{
upd(a[l], 1);
for(int i : q) ans[i] = qry(u[i]);
clr(a[l]);
return;
}
rep(i, l, r) ul[i].clear(), ur[i].clear();
int mid = l + r >> 1;
vector<int> ql, qr;
int mn = 1e9, mx = 0;
for(int i : q)
{
if(pl[i] <= mid && pr[i] > mid)
{
ul[pl[i]].push_back(i), ur[pr[i]].push_back(i);
chmin(mn, pl[i]);
chmax(mx, pr[i]);
}
else if(pr[i] <= mid) ql.push_back(i);
else qr.push_back(i);
}
per(i, mid, mn)
{
upd(a[i], 1);
for(int j : ul[i]) chmax(ans[j], qry(u[j]));
}
rep(i, mn, mid) clr(a[i]);
rep(i, mid + 1, mx)
{
upd(a[i], 1);
for(int j : ur[i]) chmax(ans[j], qry(u[j]));
}
per(i, mx, mid + 1) clr(a[i]);
solve(l, mid, ql); solve(mid + 1, r, qr);
}
int q, id[N], m;
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> m >> q;
rep(i, 1, n - 1)
{
int x, y; cin >> x >> y;
e.add(x, y); e.add(y, x);
}
dfs1(1, 0);
dfs2(1, 1);
rep(i, 1, n) if(i == top[i]) t[i].init(t[i].N + 1);
rep(i, 1, m) cin >> a[i];
vector<int> qq;
rep(i, 1, q) cin >> pl[i] >> pr[i] >> u[i], qq.push_back(i);
solve(1, m, qq);
rep(i, 1, q) cout << ans[i] << "\n";
return 0;
}
B
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 4e6 + 5;
int n, q, d[N];
string s;
void manacher(string& s)
{
string t;
int n = s.size();
t = "@#";
rep(i, 0, n - 1) t += s[i], t += '#';
t += '$';
// cerr << t << endl;
memset(d, 0, sizeof d);
int l = 0, r = 0;
rep(i, 1, n * 2 + 1)
{
if(i <= r) d[i] = min(r - i, d[l * 2 - i]);
while(t[i + d[i] + 1] == t[i - d[i] + 1]) d[i] ++;
if(i + d[i] >= r) l = i, r = i + d[i];
}
}
void init(string s)
{
int n = s.size();
string t;
rep(i, 0, n - 1) t += s[i], t += s[n - i - 1];
manacher(t);
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> q;
cin >> s; s = ' ' + s;
while(q --)
{
int k; cin >> k;
if(!(k & 1))
{
k >>= 1;
int len = min(k, n - k + 1);
int l = k - len + 1, r = k + len - 1;
auto t = s.substr(l, r - l + 1);
// cerr << t << endl;
init(t);
int m = r - l + 1;
ll ans = len;
rep(i, 1, len - 1)
{
int j = i * 4;
// cerr << j << " " << d[j] << endl;
ans += d[j] / 4;
}
rep(i, 1, len - 1)
{
int j = i * 4 - 2;
// cerr << j << " " << d[j] << endl;
ans += (d[j] + 2) / 4;
}
cout << ans << "\n";
}
else
{
k >>= 1;
int len = min(k, n - k);
int l = k - len + 1, r = k + len;
auto t = s.substr(l, r - l + 1);
init(t);
int m = r - l + 1;
ll ans = len;
rep(i, 1, len - 1)
{
int j = i * 4;
// cerr << j << " " << d[j] << endl;
ans += d[j] / 4;
}
rep(i, 1, len)
{
int j = i * 4 - 2;
// cerr << j << " " << d[j] << endl;
ans += (d[j] + 2) / 4;
}
cout << ans << "\n";
}
}
return 0;
}
C
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 2e5 + 5, M = 4e5 + 5, p = 1e9 + 7;
int fac[M], ifac[M];
ll qpow(ll a, ll b)
{
if(!b) return 1;
return ((b & 1) ? a : 1ll) * qpow(a * a % p, b >> 1) % p;
}
void init()
{
fac[0] = ifac[0] = 1;
for(int i = 1; i < M; i ++) fac[i] = 1ll * fac[i - 1] * i % p;
ifac[M - 1] = qpow(fac[M - 1], p - 2) % p;
for(int i = M - 2; i >= 1; i --) ifac[i] = 1ll * ifac[i + 1] * (i + 1) % p;
}
inline ll C(ll a, ll b)
{
if(a < b || a < 0 || b < 0) return 0;
return 1ll * fac[a] * ifac[b] % p * ifac[a - b] % p;
}
int n, a[N];
int g[4][N];
int pre[N], pre2[N];
int id[N];
inline int calc(int x, int y, bool d)
{
if(d) return (C(x + y - 1, x) + C(x + y - 1, y) - C(x + y - 2, x - 1)) % p;
else return C(x + y - 2, x - 1);
}
int pos[N];
void sol(int *a, int *g, bool rv)
{
rep(i, 1, n) id[i] = rv ? n - i + 1 : i;
g[0] = 1;
rep(i, 1, n) pos[a[i]] = i;
stack<int> s;
s.push(0);
rep(i, 1, n)
{
while(s.size() && s.top() > pos[i]) s.pop();
pre2[pos[i]] = s.top();
s.push(pos[i]);
}
s = {}; s.push(0);
rep(i, 1, n)
{
while(s.size() && a[s.top()] > a[i]) s.pop();
pre[i] = s.top();
s.push(i);
if(pre[i] != pre2[i]) g[id[i]] = 0;
else if(g[id[pre[i]]])
g[id[i]] = 1ll * g[id[pre[i]]] * calc(i - pre[i], a[i] - a[pre[i]], pre[i] != 0) % p;
}
}
inline void add(int &x, ll y) { x = (x + y) % p; }
signed main()
{
init();
ios::sync_with_stdio(0);cin.tie(0);
cin >> n; rep(i, 1, n) cin >> a[i];
rep(rv, 0, 1) rep(fp, 0, 1)
{
static int b[N];
memcpy(b, a, sizeof a);
if(rv) reverse(b + 1, b + n + 1);
if(fp) rep(i, 1, n) b[i] = n - b[i] + 1;
sol(b, g[rv << 1 | fp], rv);
}
int ans = 0;
int s = 0;
per(i, n, 1)
{
add(s, 1ll * g[2][i] * g[3][i]);
add(ans, 1ll * g[0][i] * g[1][i] % p * s);
}
s = 0;
rep(i, 1, n) pos[a[i]] = i;
per(i, n, 1)
{
int x = pos[i];
add(ans, 1ll * g[0][x] * g[2][x] % p * s);
add(s, 1ll * g[1][x] * g[3][x]);
}
cout << ans;
return 0;
}
D
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
template<int N, int M, typename _T, _T maxflow>
struct wll
{
int S, T, fst[N], nxt[M << 1], to[M << 1], cur[N], d[N], h = 2; _T w[M << 1];
void add(int x, int y, _T z)
{
nxt[h] = fst[x], fst[x] = h, to[h] = y, w[h] = z, h ++;
}
void adde(int x, int y, _T z) { add(x, y, z); add(y, x, 0); }
bool bfs()
{
memset(d, -1, sizeof d);
queue<int> q;
q.push(S);
d[S] = 0, cur[S] = fst[S];
while(!q.empty())
{
int t = q.front();
q.pop();
for(int i = fst[t]; i; i = nxt[i])
{
int j = to[i];
if(d[j] == -1 && w[i])
{
d[j] = d[t] + 1;
cur[j] = fst[j];
if(j == T) return true;
q.push(j);
}
}
}
return false;
}
_T find(int x, _T limit)
{
if(x == T) return limit;
_T sum = 0, ns;
for(int i = cur[x]; i && sum < limit; i = nxt[i])
{
int j = to[i];
cur[x] = i;
if(d[j] != d[x] + 1 || !w[i]) continue;
ns = find(j, min(w[i], limit - sum));
if(!ns) d[j] = -1;
w[i] -= ns, w[i ^ 1] += ns, sum += ns;
}
return sum;
}
_T dinic()
{
_T res = 0;
while(bfs()) res += find(S, maxflow);
return res;
}
void clear()
{
memset(fst, 0, sizeof fst);
memset(nxt, 0, sizeof nxt);
h = 2;
}
} ;
const int N = 1.5e4 + 10, M = 1.2e5 + 5;
const int inf = 1e9;
wll<N, M, int, inf> g;
int n, m, d[N], a[N];
int t;
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> m;
rep(i, 1, n) cin >> d[i];
rep(i, 1, n) cin >> a[i];
t = n * 2 + 2;
g.S = t + n + 1, g.T = t + n + 2;
rep(i, 1, n) if(d[i] != -1)
{
g.adde(g.S, t + i, a[i] * (d[i] == 0));
g.adde(t + i, g.T, a[i] * (d[i] == 1));
g.adde(t + i, i << 1, inf);
g.adde(i << 1 | 1, t + i, inf);
}
else g.adde(i << 1, i << 1 | 1, a[i]);
rep(i, 1, m)
{
int x, y; cin >> x >> y;
g.adde(x << 1, y << 1, inf);
g.adde(y << 1 | 1, x << 1 | 1, inf);
}
cout << g.dinic();
return 0;
}
E
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 5e5 + 5, M = N * 26;
template<typename T>
struct qwq {
int sa[15], rk[15], h[15], n;
T s;
void init(T _s, int l, int r)
{
s = T{0};
for(int i = l; i <= r; i ++) s += _s[i];
n = s.size() - 1;
}
void Main()
{
for(int i = 1; i <= n; i ++) sa[i] = i;
if(n <= 12)
{
sort(sa + 1, sa + n + 1, [&](int x, int y) {
return strcmp(s.data() + x, s.data() + y) < 0;
}) ;
rep(i, 1, n) rk[sa[i]] = i;
return;
}
}
void getlcp()
{
int k = 0;
for(int i = 1; i <= n; i ++)
{
if(rk[i] == 0) continue;
if(k) k --;
while(i + k <= n && s[i + k] == s[sa[rk[i] - 1] + k]) k ++;
h[rk[i]] = k;
}
}
} ;
int fst[N], nxt[M], to[M], h = 2;
int cur[N];
void add(int x, int y)
{
nxt[h] = fst[x], fst[x] = h, to[h] = y, h ++;
}
int n, m;
stack<int> stk;
void dfs(int x)
{
for(int ii = cur[x]; ii; ii = cur[x])
{
cur[x] = nxt[ii];
dfs(to[ii]);
}
stk.push(x);
}
int id(string s)
{
int res = 0;
for(char c : s) res = res * 26 + c - 'a';
return res;
}
bool vis[N];
string calc(int n, string s)
{
assert(n > 1);
int m = s.size();
memset(vis, 0, sizeof vis);
rep(i, 0, m - n) vis[id(s.substr(i, n))] = 1;
n --;
int N = pow(26, n);
rep(i, 0, N - 1) fst[i] = 0; h = 2;
rep(i, 0, N - 1)
{
rep(j, 0, 25) if(!vis[i * 26 + j])
{
int k = (i * 26 + j) % N;
add(i, k);
}
}
rep(i, 0, N - 1) cur[i] = fst[i];
stk = {};
dfs(id(s.substr(m - n, n)));
stk.pop();
while(stk.size()) s += 'a' + stk.top() % 26, stk.pop();
return s;
}
int calc(string s)
{
int len = s.size();
static qwq<string> sa;
sa = {};
sa.init(s, 0, len - 1);
sa.Main();
sa.getlcp();
int y = 0;
rep(i, 1, len) y += sa.h[i];
return y;
}
string A;
vector<tuple<ll, int, string>> all[12];
void solve()
{
int n; ll m; cin >> n >> m;
if(n >= 12)
{
auto ans = A.substr(0, n);
int s = 0;
s += max(0, n - 26);
s += max(0, n - 26 * 26 - 1);
s += max(0, n - 26 * 26 * 26 - 2);
cout << s << "\n"; cout << ans << "\n";
}
else
{
assert(all[n].size());
int l = 0, r = all[n].size() - 1;
while(l < r)
{
int mid = l + r >> 1;
if(get<0>(all[n][mid]) < m) l = mid + 1;
else r = mid;
}
auto [pres, v, u] = all[n][r];
cout << v << "\n"; cout << u << "\n";
}
}
string now;
void dfsS(int x, int c)
{
if(x >= 11) return;
all[x + 1].push_back({0, 0, now});
now += 'a' + c;
dfsS(x + 1, c + 1);
now.pop_back();
rep(i, 0, c - 1)
{
now += i + 'a';
dfsS(x + 1, c);
now.pop_back();
}
}
const int K = 30;
ll fac[K], c[K][K];
void init()
{
rep(i, 'a', 'z') A += i;
rep(i, 2, 4)
A = calc(i, A);
// cerr << A;
fac[0] = 1; rep(i, 1, K - 1) fac[i] = fac[i - 1] * i;
rep(i, 0, K - 1) c[i][0] = 1;
rep(i, 1, K - 1) rep(j, 1, i) c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
now = "a";
dfsS(0, 1);
rep(len, 1, 11)
{
for(auto &[x, y, u] : all[len])
y = calc(u);
sort(all[len].begin(), all[len].end(), [](auto& x, auto& y) { return get<1>(x) < get<1>(y); });
ll s = 0;
int cnt = 0;
for(auto &[x, y, u] : all[len])
{
int k = *max_element(u.begin(), u.end()) - 'a' + 1;
s += c[26][k] * fac[k];
x = s;
cnt ++;
if(s > 1e15) break;
}
all[len].resize(cnt);
}
}
signed main()
{
init();
ios::sync_with_stdio(0);cin.tie(0);
int t; cin >> t; while(t --) solve();
return 0;
}
F
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 1e6 + 5;
ll n;
using LL = __int128;
inline LL gets(LL r) { return r * (r + 1) / 2; }
inline LL gets(LL l, LL r) { return min((LL)2e18, gets(r) - gets(l - 1)); }
inline ll getfa(ll x) { return ceil(sqrtl(8 * x - 7)) / 2; }
inline bool sz(LL l,LL r)
{
r = min(r, (LL)n);
if(l > r) return 0;
return (r ^ l ^ 1 ^ sz(l * (l - 1) / 2 + 2, r * (r + 1) / 2 + 1)) & 1;
}
const int P = 1e7 + 3;
struct umap {
ll v[P]; int w[P];
int& operator[](ll x)
{
ll h = x % P;
while(v[h] && v[h] != x) h = (h + 1 == P ? 0 : h + 1);
v[h] = x;
return w[h];
}
} mp;
int idx = 0;
inline int ins(ll v)
{
auto& f = mp[v];
return f ? f : f = ++idx;
}
int q;
// vector<int> f[N];
int op[N];
ll ans[N], x[N], v[N];
const int M = 9e6 + 5;
bool vis[M], w[M], a[N];
struct vec {
int fst[N], nxt[N * 10], h = 2; int to[N * 10];
void add(int x, int y) { nxt[h] = fst[x], fst[x] = h, to[h] = y, h ++; }
} f;
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> q;
rep(i, 1, q)
{
cin >> op[i] >> x[i];
if(op[i] == 1) cin >> v[i];
static int tmp[15]; int h = 0;
for(ll j = x[i]; j; j = getfa(j)) tmp[++h] = ins(j);
per(j, h, 1) f.add(i, tmp[j]);
a[i] = sz(x[i], x[i]);
x[i] = ins(x[i]);
}
rep(o, 0, 59)
{
memset(w, 0, sizeof w);
memset(vis, 0, sizeof vis);
rep(i, 1, q)
{
if(op[i] == 1)
{
if(!((v[i] >> o) & 1)) continue;
bool dt = w[x[i]] ^ a[i];
if(dt)
for(int ii = f.fst[i], j = f.to[ii]; ii; ii = f.nxt[ii], j = f.to[ii])
{
if(vis[j]) break;
w[j] ^= dt;
}
vis[x[i]] = 1;
}
else
{
bool vd = 0;
for(int ii = f.fst[i], j = f.to[ii]; ii; ii = f.nxt[ii], j = f.to[ii]) if(vis[j]) { vd = 1; break; }
if(vd) ans[i] |= (ll)a[i] << o;
else ans[i] |= (ll)w[x[i]] << o;
}
}
}
rep(i, 1, q) if(op[i] == 2)
cout << ans[i] << "\n";
return 0;
}
G
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
void add(string &x, string y)
{
reverse(x.begin(), x.end());
reverse(y.begin(), y.end());
int a = x.size(), b = y.size();
x.resize(max(a, b) + 2, '0');
y.resize(max(a, b) + 2, '0');
int sum = 0;
rep(i, 0, max(a, b) + 1)
{
sum += x[i] == '1';
sum += y[i] == '1';
x[i] = '0' + (sum & 1);
sum >>= 1;
}
while(x.size() > 1 && x.back() == '0') x.pop_back();
reverse(x.begin(), x.end());
}
void rm0(string& ans)
{
reverse(ans.begin(), ans.end());
while(ans.size() > 1 && ans.back() == '0') ans.pop_back();
reverse(ans.begin(), ans.end());
}
string calc(string& s, int l, int r)
{
string x, y = "1";
rep(i, l, r - 1) if(s[i] == '1') x += '1';
rep(i, r + 1, s.size() - 1) y += s[i];
// cerr << l << " " << r << " " << x << " " << y << endl;
add(x, y);
// cerr << x << endl;
return x;
}
void solve()
{
int n; string s; cin >> n >> s;
int pos = find(s.begin(), s.end(), '1') - s.begin();
if(pos == s.size()) return cout << "0\n", void();
set<pair<int, int>> st;
int c = 0;
rep(i, 0, n - 1)
{
c += s[i] == '1';
if(s[i] == '1' && c > 1)
{
int d = n - i - 1 + c;
int xl = c - 1;
int ri = n - i - 1;
st.insert({max(c, ri), i});
}
}
int t = 0;
string ans = string(count(s.begin(), s.end(), '1'), '1');
rm0(ans);
for(auto [v, i] : st)
{
if(++t > 3) break;
auto res = calc(s, pos, i);
if(res.size() < ans.size() || (res.size() == ans.size() && res < ans)) ans = res;
}
cout << ans << "\n";
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
int t;cin >> t;while(t --) solve();
return 0;
}
H
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 12, p = 317;
int m, a[N][N], b[N][N], q;
int to3[1 << N];
const int M = 177147;
int g[M][p], g2[p][M], pw3[N], v3[1 << N];
vector<int> z[N + 1][p], h[N + 1][p], h2[N + 1][p];
inline void add(int &x, ll y) { x = (x + y) % p; }
inline int get3(int v2)
{
int s = 0;
rep(j, 0, N - 1) if((v2 >> j) & 1) s += pw3[j];
return s;
}
int A[1 << N][1 << N], B[1 << N];
int v[1 << N][1 << N];
int w[1 << N], c[1 << N];
vector<int> to[1 << N];
int fac[p], ifac[p];
ll qpow(ll a, ll b)
{
if(!b) return 1;
return ((b & 1) ? a : 1ll) * qpow(a * a % p, b >> 1) % p;
}
auto getv = [](int i) -> int {
vector<int> v;
int lst = -1;
rep(k, 0, m - 1) if(!((i >> k) & 1))
v.push_back(k - lst), lst = k;
sort(v.begin(), v.end());
i = 0; int s = 0;
for(int j : v) i |= ((1 << j - 1) - 1) << s, s += j;
return i;
} ;
auto getv2 = [](int i, int o) -> int {
vector<pair<int, int>> v;
int lst = -1;
rep(k, 0, m - 1) if(!((i >> k) & 1))
v.push_back({k - lst, (o >> lst + 1) & ((1 << k - lst) - 1)}), lst = k;
sort(v.begin(), v.end());
i = 0; o = 0; int s = 0;
for(auto [j, u] : v) i |= ((1 << j - 1) - 1) << s, o |= u << s, s += j;
return o;
} ;
void init()
{
fac[0] = ifac[0] = 1;
for(int i = 1; i < p; i ++) fac[i] = fac[i - 1] * i % p;
ifac[p - 1] = qpow(fac[p - 1], p - 2) % p;
for(int i = p - 2; i >= 1; i --) ifac[i] = ifac[i + 1] * (i + 1) % p;
rep(i, 1, (1 << m) - 1)
{
A[i][0] = 1;
if(i != ((1 << m) - 1))
for(int j = (i + 1) | i; ; j = (j + 1) | i)
{
int k = j ^ i, l = __lg(k & -k);
int s = 1;
rep(c, 0, m - 1) if((i >> c) & 1) s = s * a[c][l] % p;
A[i][k] = A[i][k ^ (1 << l)] * s % p;
if(j == ((1 << m) - 1)) break;
}
B[i] = 1;
rep(j, 0, m - 1) rep(k, 0, m - 1) if(j != k && ((i >> j) & 1) && ((i >> k) & 1))
B[i] = B[i] * b[j][k] % p;
}
rep(i, 1, m) rep(j, 0, p - 1) z[i][j].assign(1 << i - 1, 0);
rep(k, 1, m) rep(j, 0, p - 1) h[k][j] = z[k][j];
rep(i, 0, p - 1)
{
rep(k, 1, m) rep(j, 0, p - 1) h2[k][j] = z[k][j];
rep(j, 1, m - 1)
{
rep(t, 0, p - i - 1)
rep(s, 0, (1 << j - 1) - 1)
{
add(h2[j + 1][t + i][s], h[j][t][s] * ifac[i]);
add(h2[j + 1][t + i][s | (1 << j - 1)], h2[j][t][s] * ifac[i]);
}
}
int mul = 1;
rep(c, 1, min(m, i ? (p - 1) / i : m))
{
mul = mul * ifac[i] % p;
add(h2[c][i * c][(1 << c - 1) - 1], mul);
}
rep(j, 1, m)
rep(t, 0, p - 1)
rep(s, 0, (1 << j - 1) - 1)
add(h[j][t][s], h2[j][t][s]);
}
rep(i, 0, m - 1) pw3[i] = pow(3, i);
rep(i, 0, (1 << m - 1) - 1)
v3[i] = get3(i);
rep(i, 0, (1 << m - 1) - 1)
{
int i0 = getv(i);
if(i0 != i) continue;
int s = v3[i];
static int mp[1 << N];
unordered_map<int, array<int, p>> ump[N];
memset(mp, -1, sizeof mp);
for(int j = i; ; j = (j - 1) & i)
{
int j0 = getv2(i, j);
int s2 = v3[j];
if(mp[j0] != -1)
{
int k = mp[j0], k2 = v3[k];
rep(x, 0, p - 1) g[s + s2][x] = g[s + k2][x];
continue;
}
else mp[j0] = j;
int res = 0;
int lst = -1;
static int w[p]; memset(w, 0, sizeof w);
w[0] = 1;
rep(k, 0, m - 1) if(!((i >> k) & 1))
{
int nj = j & ((1 << k) - 1);
if(ump[k].count(nj))
{
memcpy(w, ump[k][nj].data(), sizeof w);
lst = k;
continue;
}
int sj = (j >> lst + 1) & ((1 << k - lst - 1) - 1);
static int hx[p];
rep(x, 0, p - 1)
hx[x] = h[k - lst][x][sj];
per(x, p - 1, 0)
{
#pragma GCC unroll 8
rep(y, 1, p - 1 - x)
w[x + y] += w[x] * hx[y];
w[x] = w[x] * hx[0];
}
rep(x, 0, p - 1) w[x] %= p;
lst = k;
array<int, p> tmp; rep(x, 0, p - 1) tmp[x] = w[x];
ump[k][nj] = tmp;
}
rep(x, 0, p - 1) g[s + s2][x] = w[x] * fac[x] % p;
if(!j) break;
}
}
rep(i, 0, (1 << m - 1) - 1)
{
int i0 = getv(i);
if(i0 == i) continue;
int s = v3[i], s0 = v3[i0];
for(int j = i; ; j = (j - 1) & i)
{
int j0 = getv2(i, j);
int s2 = v3[j], sj2 = v3[j0];
#pragma GCC unroll 8
rep(k, 0, p - 1)
g[s + s2][k] = g[s0 + sj2][k];
if(!j) break;
}
}
rep(i, 0, M - 1)
rep(j, 0, p - 1)
{
g2[j][i] = g[i][j];
}
v[0][0] = 1;
rep(i, 0, (1 << m) - 2)
{
int pci = __builtin_popcount(i);
rep(j, 0, (1 << max(0, pci - 1)) - 1)
for(int k = (i + 1) | i; ; k = (k + 1) | i)
{
int pck = __builtin_popcount(k);
add(v[k][j | ((1 << pck - pci - 1) - 1 << pci)], v[i][j] * A[k ^ i][i] * B[k ^ i]);
if(k == (1 << m) - 1) break;
}
}
rep(i, 0, (1 << m - 1) - 1) w[i] = v[(1 << m) - 1][i];
}
ll f[N + 1][1 << N];
int solve(ll q)
{
int h = 0, v[N] = {};
while(q) v[h ++] = q % p, q /= p;
chmax(h, 1);
memset(f, 0, sizeof f);
f[h][(1 << m - 1) - 1] = 1;
per(i, h - 1, 0)
{
rep(j, 0, (1 << m - 1) - 1) if(f[i + 1][j])
for(int k = j; ; k = (k - 1) & j)
{
f[i][k] += f[i + 1][j] * g2[v[i]][v3[j] + v3[k]];
if(!k) break;
}
rep(j, 0, (1 << m - 1) - 1)
f[i][j] %= p;
}
ll ans = 0;
rep(i, 0, (1 << m - 1) - 1)
{
ans += f[0][i] * w[i];
}
return (ans % p + p) % p;
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> m;
rep(i, 0, m - 1) rep(j, 0, m - 1) cin >> a[i][j], a[i][j] %= p;
rep(i, 0, m - 1) rep(j, 0, m - 1) cin >> b[i][j], b[i][j] %= p;
init();
cin >> q;
while(q --)
{
ll x; cin >> x;
cout << solve(x) << "\n";
}
return 0;
}
I
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 205, p = 1e9 + 7;
int n, m, f[N][N][N], a[N][N], b[N][N];
int c0[N][N], c1[N][N];
int c[N];
bool cmp(int *a, int *b) // a < b
{
rep(i, 1, m) if(a[i] != b[i]) return a[i] < b[i];
return 0;
}
void sol1()
{
rep(i, 1, m) b[1][i] = max(0, a[1][i]);
rep(i, 2, n)
{
memcpy(c, a[i], sizeof a[i]);
rep(j, 1, m)
{
if(a[i][j] != -1)
{
c[j] = a[i][j];
continue;
}
// c = 0
c[j] = 0;
rep(k, j + 1, m) c[k] = a[i][k] == -1 ? 1 : a[i][k];
if(cmp(c, b[i - 1]))
{
c[j] = 1;
}
if(cmp(c, b[i - 1]))
{
cout << -1;
exit(0);
}
}
memcpy(b[i], c, sizeof c);
}
// rep(i, 1, n) rep(j, 1, m) cerr << b[i][j] << " \n"[j == m];
}
inline void add(int &x, ll y) { x = (x + y) % p; }
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> m;
rep(i, 1, n)
{
string s; cin >> s;
rep(j, 1, m)
{
if(s[j - 1] == '.') a[i][j] = -1;
else a[i][j] = s[j - 1] == '1';
}
}
sol1();
rep(i, 1, m) cout << b[n][i]; cout << " ";
memcpy(a[n], b[n], sizeof b[n]);
rep(i, 1, m) rep(j, 1, n)
{
c0[i][j] = c0[i][j - 1] + (a[j][i] == 0);
c1[i][j] = c1[i][j - 1] + (a[j][i] == 1);
}
rep(i, 1, n) rep(j, i, n) f[m + 1][i][j] = 1;
per(i, m, 1)
{
per(l, n, 1) rep(r, l, n)
{
if(c1[i][r] == c1[i][l - 1]) add(f[i][l][r], f[i + 1][l][r]);
if(c0[i][r] == c0[i][l - 1]) add(f[i][l][r], f[i + 1][l][r]);
rep(k, l, r - 1)
{
if(c1[i][k] == c1[i][l - 1] && c0[i][r] == c0[i][k])
add(f[i][l][r], 1ll * f[i + 1][l][k] * f[i + 1][k + 1][r]);
}
// cerr << i << " " << l << " " << r << " " << f[i][l][r] << endl;
}
}
cout << f[1][1][n];
return 0;
}
J
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
#define int ll
int solve(ll m)
{
int t = __lg(m);
if((m & -m) == m)
{
if(t & 1) return 1e9;
return 0;
}
return solve((1ll << t + 1) - m) + 1;
}
void solve()
{
ll n, m; cin >> n >> m;
// static int T = 0; m = ++T; n = 5; cerr << n << " " << m << endl;
if(n % 2 == 0) return cout << "NO\n", void();
if(solve(m) * 2 <= n) cout << "YES\n";
else cout << "NO\n";
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
int t;cin >> t;while(t --) solve();
return 0;
}
K I.
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 2e6 + 5;
int n, m;
ll v, da, db, a[N], b[N];
int f[N];
ll c[N]; int typ[N], id[N][2];
int na[N], nb[N];
int px[N], py[N];
int pa[N], pb[N];
vector<int> upd[N];
struct sgt {
int a[N << 2];
sgt() { memset(a, 0x3f, sizeof a); }
void pu(int x) {a[x] = min(a[x << 1], a[x << 1 | 1]);}
void upd(int q, int l, int r, int x, int v)
{
if(l == r) return a[x] = v, void();
int mid = l + r >> 1;
if(mid >= q) upd(q, l, mid, x << 1, v);
else upd(q, mid + 1, r, x << 1 | 1, v);
pu(x);
}
} t;
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> m >> v >> da >> db;
rep(i, 1, n) cin >> a[i];
rep(i, 1, m) cin >> b[i];
int h = 0, x = 1, y = 1;
while(x <= n || y <= m)
{
if(y > m || a[x] < b[y])
{
if(!h || c[h] != a[x]) c[++h] = a[x];
typ[h] |= 1, id[h][0] = x, px[x] = h;
x ++;
}
else
{
if(!h || c[h] != b[y]) c[++h] = b[y];
typ[h] |= 2, id[h][1] = y, py[y] = h;
y ++;
}
}
na[n] = n; nb[m] = m;
for(int i = n - 1, j = n; i >= 1; i --)
{
while(a[j] - a[i] > da) j --;
if(i == j) return cout << -1, 0;
na[px[i]] = px[j];
}
for(int i = m - 1, j = m; i >= 1; i --)
{
while(b[j] - b[i] > db) j --;
if(i == j) return cout << -1, 0;
nb[py[i]] = py[j];
}
memset(f, 0x3f, sizeof f);
f[1] = 1;
auto updf = [&](int x) { t.upd(x, 1, h, 1, f[x] - (pa[x] != pb[x])); };
updf(1);
rep(i, 1, h)
{
if(typ[i] == 3)
chmin(f[i], t.a[1]);
sort(upd[i].begin(), upd[i].end(), [](int x, int y) { return max(pa[x], pb[x]) > max(pa[y], pb[y]); });
int mnf = 1e9;
for(int j : upd[i])
{
bool ia = pa[j] == i, ib = pb[j] == i;
if((ia && ib) || f[j] >= mnf)
{
f[j] = 1e9, updf(j);
continue;
}
mnf = f[j];
if(ia)
{
pa[j] = na[pa[j]], upd[min(pa[j], pb[j])].push_back(j);
f[j] += pa[j] != pb[j], updf(j);
}
else
{
pb[j] = nb[pb[j]], upd[min(pa[j], pb[j])].push_back(j);
f[j] += pa[j] != pb[j], updf(j);
}
}
if(typ[i] == 3)
{
pa[i] = na[i];
pb[i] = nb[i];
if(i == h) continue;
upd[min(pa[i], pb[i])].push_back(i);
f[i] += 1 + (pa[i] != pb[i]);
updf(i);
}
}
cout << f[h];
return 0;
}
K II.
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 2e6 + 5;
struct BIT {
int a[N];
vector<int> u;
void upd(int q, int v) { u.push_back(q); for(int i = q; i; i -= (i & -i)) chmax(a[i], v); }
int qry(int q) { int ans = 0; for(int i = q; i < N; i += (i & -i)) chmax(ans, a[i]); return ans; }
void clr() { for(int q : u) for(int i = q; i; i -= (i & -i)) a[i] = 0; u.clear(); }
} t[2];
int n, m;
ll v, da, db, a[N], b[N];
int f[N];
ll c[N]; int typ[N], id[N][2];
int na[N], nb[N];
int px[N], py[N];
vector<int> ea[N], eb[N];
int dfna[N], dfnb[N], depa[N], depb[N], sa[N], sb[N];
void dfs(int x, vector<int> *e, int *dfn, int* dep, int *sz, int &ts)
{
sz[x] = 1; dfn[x] = ++ts;
for(int i : e[x]) dep[i] = dep[x] + 1, dfs(i, e, dfn, dep, sz, ts);
}
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> m >> v >> da >> db;
rep(i, 1, n) cin >> a[i];
rep(i, 1, m) cin >> b[i];
int h = 0, x = 1, y = 1;
while(x <= n || y <= m)
{
if(y > m || a[x] < b[y])
{
if(!h || c[h] != a[x]) c[++h] = a[x];
typ[h] |= 1, id[h][0] = x, px[x] = h;
x ++;
}
else
{
if(!h || c[h] != b[y]) c[++h] = b[y];
typ[h] |= 2, id[h][1] = y, py[y] = h;
y ++;
}
}
na[n] = n; nb[m] = m;
for(int i = n - 1, j = n; i >= 1; i --)
{
while(a[j] - a[i] > da) j --;
if(i == j) return cout << -1, 0;
na[px[i]] = px[j];
ea[px[j]].push_back(px[i]);
}
for(int i = m - 1, j = m; i >= 1; i --)
{
while(b[j] - b[i] > db) j --;
if(i == j) return cout << -1, 0;
nb[py[i]] = py[j];
eb[py[j]].push_back(py[i]);
}
rep(i, 1, h) reverse(ea[i].begin(), ea[i].end());
rep(i, 1, h) reverse(eb[i].begin(), eb[i].end());
int ts = 0;
dfs(h, ea, dfna, depa, sa, ts);
ts = 0;
dfs(h, eb, dfnb, depb, sb, ts);
ts = 0;
memset(f, 0x3f, sizeof f);
auto upd = [&](int x, int y) { t[y].upd(dfna[x], dfnb[x]); };
f[1] = 1 + depa[1] + depb[1];
int mn = f[1], id = 0;
upd(1, id);
rep(i, 2, h) if(typ[i] == 3)
{
f[i] = mn + 1;
if(t[id].qry(dfna[i]) > dfnb[i]) chmin(f[i], mn - 1);
else if(t[id].qry(1) > dfnb[i] || t[id].qry(dfna[i]) > 0) chmin(f[i], mn);
else if(t[id ^ 1].qry(dfna[i]) > dfnb[i]) chmin(f[i], mn);
if(f[i] < mn) mn = f[i], id ^= 1, t[id].clr(), upd(i, id);
else if(f[i] == mn) upd(i, id);
else upd(i, id ^ 1);
}
cout << f[h];
return 0;
}
L
#include<bits/stdc++.h>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i ++)
#define per(i, s, t) for(int i = (s); i >= (t); i --)
template<typename T, typename T2>
inline void chmin(T &x, T2 &&y) { x = min(x, y); }
template<typename T, typename T2>
inline void chmax(T &x, T2 &&y) { x = max(x, y); }
typedef long long ll;
const int N = 5e5 + 5, p = 1e9 + 7;
int n, q, a[N], s[N], inv[N];
vector<int> L[N], R[N];
inline int calc(int l, int r)
{
ll sum = s[r] - s[l - 1], c = r - l + 1;
int avg = 1ll * sum * inv[c] % p;
return 1ll * avg * avg % p;
}
void init()
{
inv[1] = 1;
rep(i, 2, n) inv[i] = 1ll * inv[p % i] * (p - p / i) % p;
rep(i, 1, n)
{
ll s = 0;
for(int l = 1; l <= n; l += i)
{
int r = min(n, l + i - 1);
L[i].push_back((s += calc(l, r)) %= p);
// cerr << i << " " << l << " " << r << " " << s << endl;
}
s = 0;
for(int r = n; r >= 1; r -= i)
{
int l = max(1, r - i + 1);
R[i].push_back((s += calc(l, r)) %= p);
}
}
}
inline void add(int &x, ll y) { x = (x + y) % p; }
signed main()
{
ios::sync_with_stdio(0);cin.tie(0);
cin >> n >> q;
rep(i, 1, n) cin >> a[i];
sort(a + 1, a + n + 1, greater<>());
rep(i, 1, n) s[i] = (s[i - 1] + a[i]) % p;
init();
rep(o, 1, q)
{
int l, r; cin >> l >> r;
int k = n / l;
int d = n - k * l;
if(1ll * k * (r - l) < d)
{
cout << -1 << "\n";
continue;
}
int ans = 0;
int k2 = l == r ? 0 : d / (r - l), k1 = max(0, k - k2 - 1);
// cerr << k << " " << k1 << " " << k2 << endl;
if(k2) add(ans, R[r][k2 - 1]);
if(k1 > 0) add(ans, L[l][k1 - 1]);
if(k2 < n) add(ans, calc(l * k1 + 1, n - k2 * r));
cout << ans << "\n";
}
return 0;
}
M
Please use C99。
main() { puts("D"); }

浙公网安备 33010602011771号