随机化

Kazaee

典。随机赋权,查询是否为 \(k\) 的倍数,多次赋权即可。

Aulvwc

非正解做法,但大概率正确(实际上过不了 Hack)。

套路的,考虑让每个 \(a_i\) 减去整体的平均值,问题转换为让两个集合的和均为 \(0\)

我们每次随机打乱 \(a\) 数组,并贪心的将其插入两个堆中,最后判断即可。

Code

ABC238G Cubic?

先对所有 \(a_i\) 质因子分解。

查询为是否所有质因子都出现了 \(3k\) 次。

考虑给每个质因子一个随机权值,现在要处理类似三进制异或之类的东西。

发现可以用 \(h_1,h_2,h_1\operatorname{xor} h_2\) 维护。

异或和后查询即可。

Submission

ABC272G Yet Another mod M

由于同余的性质可得,如果 \(a_x\equiv a_y \pmod p\),则 \(|a_x-a_y|\bmod p=0\)

所以我们随机选择 \(2\)\(a_i,a_j(i\ne j)\) 的话,由于答案集合大于 \(2\),记 \(d=|a_i-a_j|\),则 \(m|d\) 的概率是 \(\dfrac{1}{4}\)

由这个性质直接做即可。

Submisson

Ghd

由于要求数量超过一半,因此可以考虑随机化,每次有 \(\dfrac{1}{2}\) 的概率正确。

具体实现时,先将随机的数的因数存下来,记为 \(d_i\)

\(m_i=\gcd(a_i,x)\),则 \(pos_i\)\(\min_i(m_i\le d_i)\),令 \(cnt_i\)\(i\)\(\gcd\) 中的出现次数,初始时 \(cnt_{pos_i}=1\),(这一过程类似离散化),\(cnt_i=\sum_{d_i|d_j}cnt_j\),直接转移即可。

我们取阈值 \(w=10\),错误概率为 \(2^{-10}\)

Code

GCD Groups 2

考虑贪心,和第一题思路类似,维护两个堆。

我们每次考虑如下选择:

  • 加入第 \(1\) 堆后,\(a_i\)\(\gcd\) 不产生任何影响,则将其放入第 \(2\) 堆。
  • 否则将其放入第 \(1\) 堆。

这样显然是可以被卡的。

我们可以多做几次,随机排列 \(a_i\),正确性提升。

Code

BJOI2014 想法

思考问题:对于 \(n\) 个均匀随机分布变量 \(a_1,a_2,a_3\dots a_n \in[1,V]\),从小到大排序,则 \(a_1\) 的期望大小为 \(\dfrac{V}{n+1}\)

如果我们知道了最小值和 \(a_1\) 的平均值,则 \(n=\dfrac{V}{a_1}-1\)

于是,我们对每个点多次随机赋权,且维护该点能到达的点的最小值。

套用上面的做法即可。

Submission

NOI 2024 集合

\(s_l\) 表示最长的 \(r\),使得询问 \([l,r]\) 回答是 Yes

任务转为求出 \(s_i\)

显然,对于 \(l<n\)\(s_l\le s_{l+1}\)

使用双指针算法。

进一步的,我们把同样的 \(a_{i,j,0/1/2}\)\(j\) 为下标) 放到一起,维护 \(c_{i,j}\) 表示现在的限制(\(i\) 表示两个序列中的哪一个,\(j\) 表示元素大小,限制指 \(a_{i,k,0/1/2}=j\)\(i\) 组成的集合),暴力开 set 用 map 维护显然是不可取的,采用 Xor Hash 即可,当限制相同(\(c_{0,i}=c_{1,j}\) 可以全部匹配)时才可以保证合法。

\(cnt\) 表示不匹配的 \(x\) 的个数。

先构造随机序列 \(s_{1\sim n}\),每次消除原先的贡献,异或上 \(s_x\),并加入新的贡献,注意:两个序列的贡献是恰好相反的(用 \(\pm1\) 来表示),对于一个限制,如果贡献此时不为 \(0\),则对 \(cnt\) 产生 \(1\) 的贡献。

开 umap 可以做到 \(\mathcal O(n+q)\)

Submission

Olha and Igor

发现随机选择 \(x,y,z\),实际上答案为根节点的左右儿子概率最大,记为 \(u,v\)

则可以通过 \(n\) 次询问 \((u,v,i)\) 得出根的值。

Submission

posted @ 2024-05-15 13:02  WhisperingWillow  阅读(16)  评论(0)    收藏  举报