COCI2021-2022#2

T3

点编号为 \(0\sim 2^n-1\) 的图,\(u,v\) 有边当且仅当 \(u\oplus v\) 的 popcount 等于 1。给定一棵 \(n+1\) 个点 \(n\) 条边的树,把它塞进图里 \(2^{n-1}\) 次,使得每条图中的边恰好对应一条树边,图中的点不限制。\(n\leq 16\)

构造题似一似先。

发现图总共就只有 \(n2^{n-1}\) 条边,不妨把边按照在哪一位不同分类,那么恰好有 \(n\) 类,每类 \(2^{n-1}\) 条边,于是有一个目标就是每棵树都在每一类里面各选一条边。

考虑怎么放第一棵树,假设用图中的 \(0\) 去对应树根。我们希望对于第 \(1\sim n\) 条树边,恰好对应了图上在第 \(0\sim n-1\) 位不同产生的边,于是我们在图上结点 \(u\) 经过第 \(i\) 条边之后,就走到图上结点 \(u\oplus 2^{i-1}\)。接下来只需要选择若干个起点进行这个过程,且使用的边不重复就能达成目标。

观察这个过程,设 \(T_{x,y}\) 表示用图中的 \(x\) 去对应树根,树上结点 \(y\) 对应的图上编号。令 \(a_i\) 表示在树上从树根走到 \(i\) 经过的边集合的二进制表示,则 \(T_{x,y}=x\oplus a_y\)。考虑什么时候会使用一条重复的边 \((x,y)\)

  • \(x\oplus y\) 的 popcount 等于 1。
  • 存在两个不同的起点 \(i,j\),满足从它们出发均会经过 \((x,y)\)

由于 \(x,y\) 唯一确定了边的类型,即确定了树边,设这条树边连接树上的 \((u,v)\),那么有 \(T_{i,u}=T_{j,u}\)\(T_{i,u}=T_{j,v}\)。不难发现第一种情况不可能出现,第二种情况意味着 \(i\oplus a_u=j\oplus a_v\)\(i\oplus j=a_u\oplus a_v\),而 \(u,v\) 由一条树边直接连接,\(a_u\oplus a_v\) 的 popcount 值为 1。

至此我们得到,如果对于一个起点集合 \(S\),其中任意两个不同元素 \(i,j\) 满足 \(i\oplus j\) 的 popcount 值不为 1,就一定不会出现非法情况。于是可以简单构造 \(S\)

T4

给定 \(n,l,r_{1\cdots n}\),在 \([1,l]\) 上不重叠地放置 \(1\sim n\),满足距离 \(i\) 最近的元素与 \(i\) 的距离至少是 \(r_i\),求方案数 \(\bmod 10^9+7\)\(n\leq 50,n\leq l\leq 10^4,r_i\leq l\)

考虑如果固定了放置的顺序如何计算方案数,比如一个 \(r\) 的排列为 \(\{1,4,2,3\}\),那么 1,4 的距离至少是 4,4,2 的距离至少是 4,2,3 的距离至少是 3,方案数就是 \(\binom{l-(4-1)-(4-1)-(3-1)}{n}\)。类比可得若确定了 \(r\) 的顺序,则方案数为 \(\binom{l-\sum\max\{r_i,r_{i+1}\}+n-1}{n}\),那么只需要对 \(\sum \max\{r_i,r_{i+1}\}\) 进行 dp。

这种形式的 dp 不妨考虑这样一个模型:从小到大地加入 \(r\),由于求的是 \(\sum \max\),所以如果产生贡献可以方便地计算;已经加入的数分为若干段,每段之间相邻的数的贡献已经结算,最终希望知道只剩一段时的答案。设 \(f_{S,j}\) 表示当前已经结算的贡献为 \(S\),剩余 \(j\) 段的方案数,最终的答案是 \(\sum \binom{l-S+n-1}{n}f_{S,1}\),考虑转移:

  • \(f'_{S,j}\times(j+1)\to f_{S,j+1}\):新开一段,有 \(j+1\) 个空隙可以放,没有新贡献结算;
  • \(f'_{S,j}\times 2j\to f_{S+r_i,j}\):放在某一段的两边,有 \(j\) 段各有两边,结算 \(r_i\) 的贡献;
  • \(f'_{S,j}\times(j-1)\to f_{S+2r_i,j}\):放在两段的中间把它们合成一段,有 \(j-1\) 个空隙,结算 \(2r_i\) 的贡献。

复杂度 \(O(n^2l)\)

T5

给出 \(n\) 个区间 \([l_i,r_i]\),定义一次覆盖 \([x,y]\) 合法当且仅当 \(1\leq x\leq y\leq n\),且满足 \([x,y]\) 中的区间任意两个交集为空。\(q\) 次询问给定 \([L,R]\),求最少覆盖次数使得 \([L,R]\) 内每个元素都被覆盖至少一次。\(n,q\leq 2\times 10^5,l_i,r_i\leq 10^9\)

一个贪心:每次询问从 \(L\) 开始选尽可能长的段。\(O(qn^2)\)

预处理一点的贪心:\(O(n^2)\) 预处理 \(nxt_i\) 表示最大的 \(j\) 满足第 \(i\) 个区间和第 \([i+1,j]\) 个区间交集为空,\(to_i\) 表示从 \(i\) 开始,一次覆盖最远能到的地方;每次询问暴力跳 \(l\gets to_l+1\) 直到 \(l>r\)\(O(nq)\)

再预处理一点:\(nxt_i\) 可以把区间端点离散化后从后往前做线段树区间覆盖区间求 \(\min\)\(to_i\) 的本质是满足 \(\min\{nxt[i,j]\}\ge j\)\(j\),可以配合 \(nxt\) 的 ST 表二分; 询问可以预处理倍增 \(f_{i,j}\) 表示 \(i\) 进行 \(2^j\)\(i\gets to_i+1\) 到达的位置。\(O((n+q)\log n)\)

好像有好写很多的做法,但是我只想到这种不用动脑子的写法。

posted @ 2022-09-29 21:13  摸鱼酱  阅读(46)  评论(0编辑  收藏  举报