Loading

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\) 中的分治中心,处理贡献。对于每个询问,直接枚举两个树的分治中心,用预处理的权值可以直接计算。

另外卡不满的暴力貌似能多冲好多分。

posted @ 2023-07-10 21:51  Cafard  阅读(18)  评论(0)    收藏  举报