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)\)

posted @ 2024-02-29 15:01  wtcqwq  阅读(13)  评论(0)    收藏  举报