2021 Summer Petrozavodsk Camp, Day 3 IQ test (XXII Open Cup, Grand Prix of IMO)

发布时间 2023-05-09 15:08:33作者: 275307894a

AND

先看最小值是不是所有的子集,如果不是就无解,否则把剩下的中间塞一个最小值就好了。

submission

Math

移项,平方差变成 \(a_j=(k-a_i)(k+a_i)\),爆枚 \(k-a_i\)\(k+a_i\) 就是 \(O(A\ln A)\) 的。

submission

Fancy Formulas

首先我们发现操作不改变 \((a+b)\bmod p\),因此如果两个不一样就无解。

一个手完一下就可以发现的事情是操作 \(k\) 次之后第一个数形如 \(2^ka-q(a+b)\),其中 \(q\in[0,2^k)\)。因为 \(p\) 是质数,所以可以枚举 \(k\) 然后计算出 \(q\) 看看在不在这个范围内。当 \(k>\log p\) 的时候就一定有解了。时间复杂度 \(O(T\log ^2p)\)

submission

Hamiltonian

没意思,想一想大概可以想出这样几个构造:

  • \(n\) 个点的完全图:\(\frac{n(n-1)}{2}\)
  • \(n\) 个点的完全图有一个点挂出一个点:\(n-1\)
  • \(n\) 个点的完全图有两个点同时连向第 \(n+1\) 个点:\(\frac{n(n+1)}{2}-1\)
  • \(n\) 个点的完全图挂出 \(m\geq 2\) 个点的链:\(\frac{n(n+3)}{2}+m-4\)

然后大概把这四种情况拼起来就覆盖了 \([1,60]\) 了。

submission

Glory Graph

看上去这两种情况分开算是没有办法算的,看看相减有没有办法能抵消掉某些项。

以下图片中实线表示一种颜色,虚线表示另一种颜色,没有连边表示任意。

image

前一种只需要枚举对角两个点然后看和他们分别连不同颜色的点的个数,第二种只需要枚举实线两端点然后看均连另一种颜色的点的个数即可。都可以 bitset ,时间复杂度 \(O(\frac{n^3}{\omega})\)

submission

Deleting

首先有一个比较愚蠢的 dp :设 \(dp_{i,j}\) 表示将 \([i,j]\) 区间消去最小代价,大概是两种转移:

  • \(i,j\) 匹配,有 \(\max(cost_{i,j},dp_{i+1,j-1})\to dp_{i,j}\)
  • \(i,k\) 匹配,有 \(\max(dp_{i,k},dp_{k+1,j})\to dp_{i,j}\)

这是 \(O(n^3)\) 的并且不太好上一般 dp 的优化方法。所以我们考虑万能 bitset,他真的好喜欢bitset

具体的,我们从小到大计算 \(dp_{i,j}\) 的值,当我们确定 \(dp_{i,j}\) 的值之后考虑扩展。

第一种转移是平凡的,第二种转移以往右转移为例,你需要找到一个位置 \(k\),使得 \(dp_{j+1,k}\) 被计算过,并且 \(dp_{i,k}\) 没有被计算过,这可以用 bitset 的 & 操作和 Find_firstFind_next 来实现。

然后大概就做完了,时间复杂度 \(O(\frac{n^3}{\omega})\),如果带个 \(n^2\log n\) 有可能会被卡常,以及 CF 上 \(64\) 位语言的 bitset 特别慢。

submission

Eulerian

挺神秘的。

发现具有神秘的 \(60\) 次询问,不知道能干吗。

唯一能考虑的似乎只有欧拉回路的充要条件:每个点度数为偶数且联通。联通题目里已经保证了,只需要考虑度数的问题。

大概会联想到某些著名的随机 hash 题比如 CF1746F,判每个都是偶数可以变成判子集加和,单次正确率是 \(\frac{1}{2}\),二项式定理容易证明。

所以我们只需要能对一个随机子集计算其度数之和的奇偶性即可。

我们考虑问出这个子集内的边数 \(a\) 以及其补集的边数 \(b\) ,那么在这两个点集之间的边数就是 \(m-a-b\)。这个数的奇偶性与这个子集的度数和奇偶性一致,因为子集内的边贡献两次。

所以我们可以问 \(29\) 个子集,正确率 \(1-2^{-29}\) 可以接受。

submission

Intellectual Implementation

牛逼题,场上写出来的队真的太厉害了!

首先因为这是个 IQ 场,所以应该不是大力数据结构的题。仿照 G 的思路先容斥,现在我们需要数三个点之间有一条边,两条边,三条边的个数。

一条边和两条边的三元组个数都需要求出和某个矩形相交的矩形个数,考虑这个怎么求。二维的问题太困难了,扫描线转化成一维问题。和某个矩形相交的大概就两类:在这个矩形的上边出现之前上边就出现了的,和上边出现了之后再出现的,这个可以按照 \(x\) 坐标排序,然后变成求和某个线段相交直线有多少的问题,转化成求不交只需要一条线段左端点大于另一个右端点即可,都可以树状数组维护。

但是三条边就不是那么好做的了。我们考虑选择最上边最下面的矩形的最上边考虑,这时依然转化成线段问题,我们要求的是与 \([u_i,d_i]\) 相交的线段中相交的对数。考虑选取相交区间的最右边的点计算,则假设某个点被覆盖 \(a\) 次,那么对答案贡献 \(a\choose 2\) 次。

这样会算重啊?没关系,我们说过只在最右边的点考虑,因此可以减去每个区间右端点缩小 \(1\) 之后的贡献,就是恰好在相交区间右端点取到的贡献。你需要写一个线段树支持区间加,区间查询平方和,则维护二次项和,一次项和,常数和即可。

时间复杂度 \(O(n\log n)\) 拥有巨大常数。submission