7/10 考后总结
时间安排
8:30--9:30
读题,T1乍一看有点像 min-max 的模型,不过并不能简化问题,考虑计算出每个状态是否合法,然后直接做 DP ,T2不太知道怎么做。
9:30--9:50
T2,对每个右端点暴力存左端点,可以拿 bitset 优化一下,做到 \(n^3/w\) 。
9:50--11:50
T1,问题等价于给出 \(2^n\) 集合 p 和 \(f_{p,j}\),判断所有可能的 \(i\) ,其 \(\sum_p f_{p,|i\&p|}\) 是否满足条件。
考虑搞个超集并集什么的做容斥。
不会。
11:50--12:00
把 T1,T3 暴力写了。
12:00--13:00
想 T1 。
回顾反思
T1:
魔改 FWT 。
考虑实际上是对于每个 \(i\) 求 \(\sum_{p=0}^{2^n-1}f_{p,|i\&p|}\) 是等于 \(2^n\) 。
可以构造函数
\(g_{i,k}=\sum_p\sum_j[j-|i\&p|=k]f_{p,j}\)
最终只关心 \(g_{i,0}=2^n\) 是否成立。
发现其形式与 FWT \(g_i=\sum (-1)^{|i\&j|}f_j\) 的形式类似。
考虑每一位时,当且仅分治的两边都为 1 时使得式子中 \(-|i\&p|\) 有 -1 的贡献;否则无影响。
那么可以类似改写 FWT 为:
\(g1'_k=g1_k+g2_k\)
\(g2'_k=g1_k+g2_{k+1}\)
进一步的,由于 \(f_{p,j}\) 初始时都为 0/1 ,且最终只关心是否等于全集大小 \(2^n\) ,那么可以用乘法代替,只看最终是否等于 1 。
\(g1'_k=g1_k*g2_k\)
\(g2'_k=g1_k*g2_{k+1}\)
进一步地,由于 \(f_{p,j}\) 的第二维全是 0/1 ,且只涉及乘法,那么可以压为一个 int ,用位运算代替原运算。
\(g1'=g1\&g2\)
\(g2'=g1\&(g2>>1)\)
那么只关心 \(g_i\&1\) 是否成立。
T2:
有贪心做法。
固定一个左端点 i 后,另初始区间 \([l,r]\) 为 \([i,i]\) 。
每次查看区间内每个点最近能跳到区间外右边的哪个点,设这个位置为 \(x\) ,更新区间为 \([i,x]\) 。
那么每个 \(i\) 贡献的答案就是这样跳的次数。
考虑优化。
对每个 \(i\) 记一个 \(f_i\) ,初值为 inf 。
从右往左枚举左端点,对于每个可以跳跃的关系 \((x,y)\) ,令 \(i\in[x,y-1]\) 的 \(f_i\) 对 \(y\) 取 min 。
那么 \(i\) 的答案就是只考虑 \(i\in[i,n]\) 的 \(f_i\) 的严格上升前缀最大值序列的长度 (可能需要因为边界对值 -1)。
用吉司机线段树维护严格上升前缀最大值序列长度和即可。
T3:
感觉是简单题(。
最近没怎么写过点分治有点生了。
给树 \(T1,T2\) ,多次询问 \(x,y\) ,求一个 z ,使得 \(dis(T1,x,z)+dis(T2,y,z)\) 和最小,求这个值。
考虑对 T1 做点分治,那么对于每个分治部分, z 对 x 的贡献分别有常数 \(d_z\) ,即在 \(T1\) 中里分治中心的距离,那么对于 \(T2\) ,就是要求 z 使得 \(d_z+dis(T2,z,y)\) 最小,可以直接建虚树后换根 dp 。
于是就是点分治套虚树换根 dp 。
另外也存在更好写的做法,
依旧是枚举 \(T1\) 的分治中心,对于每个点直接枚举 \(T2\) 中的分治中心,处理贡献。对于每个询问,直接枚举两个树的分治中心,用预处理的权值可以直接计算。
另外卡不满的暴力貌似能多冲好多分。

浙公网安备 33010602011771号