2.23 比赛
A
Subtask 1(10pts)
对每个点对维护一个 map,维护 \(k\) 棵树都有的点对的数量。
Subtask 4(15pts)
对上述算法进行优化。
设 \(f_{i,j,t}\) 表示是否存在一棵树使得 \((i,j)\) 路径上包含 \(t\)。\((i,j)\) 的答案为 \(\sum_t f_{i,j,t}\)。时间复杂度 \(O(n^2k^2)\)。
Subtask 2 5(40pts)
对上述算法进行优化。发现事实上是一个或的关系,自然联想到 bitset。
假设在第 \(m\) 棵树上,路径 \((i,j)\) 包含的点构成的集合用 bitset 表示为 \(S_{m}\),则 \(f_{i,j,k}= |_S S_m\)
把上面的做法用 bitset 维护即可。时间复杂度 \(O(\frac {n^2k^2} w)\)。
Subtask 3、6(40~100pts)
写的比较优秀的 bitset 是可以过的。
需要尝试以下优化
- 严格控制各类 count reset 之类操作的次数
- 注意到 \(ans_{i,j}=ans_{j,i}\) ,在各个阶段的操作中,都不要重复计算
- 各类基本的常数优化方法(例如 快读、long long 改 int 等)
- bitset 的写法较为优秀
- 发现链跑的比较慢(递归深度较深),可以特判。(当然不特判是可以过的)
具体 bitset 写法可以是这样的:
在 dfs 里对每一个起点 \(i\),维护 bitset \(x\),\(x_j\) 表示 \((i,j)\) 路径上的点集。易知,$x_u=x_{fa_u} + u $。
在 dfs 完成以后,通过对所有点对 \((i,j)\) 满足 \(i\le j\),维护 \(ans_{i,j} \to ans_{i,j}|x_j\),即可。
时间复杂度 \(O(\frac{n^2k^2}w)\)。
以 TestCase 13 为例,相比最初的 bitset(1033ms),最后的 AC 代码大约为 606ms,提升 \(40\%\)。最慢的点在 TestCase 8,跑了 3740ms。
Subtask inf(100pts)
虽然但是,正解还是要学的。
考虑转化题面的情况,对于一个点 \(z\) 不在 \((x,y)\) 路径上,意味着以 \(z\) 为根,\(x,y\) 永远在 \(x\) 的子树内。考虑随机权值哈希,对每个点记录删去后形成的子树编号。用随机权值哈希判断是不是在一个子树内是不难题。
B
Subtask 1 (30pts,但出题人数据造挂了)
爆搜。具体来说,枚举红色侏儒和紫色侏儒的位置序列。这个数量一定不超过 \(2^{n+m}\) 种。然后我们考虑什么时候合法。在一次戏法中,会产生三段区间。而相邻两个侏儒之间被经过三遍 \(\leftrightarrow\) 是三段区间的交集。
时间复杂度 \(O(2^{n+m}k)\)
Subtask 3 (50pts)
首先,我们发现一个戏法只和四个坐标的位置关系有关。
考虑一个戏法什么时候是好的:只有 \(acbd,acdb,cabd,cadb\) 是好的。
考虑 \(dp_{i,j}\) 表示选择了 \(i\) 个红衣侏儒和 \(j\) 个紫衣侏儒,确定会做贡献的戏法有哪些。也就是,要么 \(a\in [c,d]\),要么 \(c\in [a,b]\)。
然后如果下一个侏儒是第 \(i+1\) 个侏儒,那么如果 \(c\le j<d\) 会对其做出 \(p\) 的贡献。如果是 \(j+1\),则为 \(a\le i <j\)。
时间复杂度 \(O(nm+(n+m)k)\)。
Subtask 4(100pts)
拿线段树、 set 之类的维护就可以。
C
比较神仙题。
Subtask 1(20pts)
考虑状态压缩dp。\(dp[i][j][S]\) 表示两个人分别在 \(i,j\),且是否有传送门的状态为 \(S\) 时的最小次数。
再考虑,枚举起始点即可。\(O(2^nn^3)\)。

浙公网安备 33010602011771号