[算法竞赛] 几个随机化问题

CF1114E
题意:

交互题。

有一个长度为 n n n 的序列 a a a,保证它从小到大排序后是个等差数列。你不知道这个序列长什么样,但你可以询问:

  • ?   i ?\ i ? i 表示询问 a i a_i ai 的值;
  • >   x >\ x > x 表示询问序列中是否存在严格大于 x x x 的数。 你可以问不超过 60 60 60 个询问。

现在,你需要求出这个等差数列的首项(也就是 a a a 中的最小值)和这个等差数列的公差(也就是等差数列中相邻两个数的差)。

2 ≤ n ≤ 1 0 6 , 0 ≤ a i ≤ 1 0 9 2\le n\le 10^6,0\le a_i\le 10^9 2n106,0ai109

我们会用30次询问求出序列中的最大值,此时考虑如何求出公差。

显然地,我们从序列里随便选数得到若干个 m x − a i mx - a_i mxai ,他们的gcd必然是公差的约数。

其实到这里就很自然地会想到随机了, 30 30 30 d d d 的倍数的gcd等于 d d d 的概率等价于随机选 30 30 30 个自然数gcd等于 1 1 1 的概率,显然超高。

CF1746F
题意:

给出一个长度为 n n n 的数组 a a a 和以下两种操作:

  • 1   i   x 1\ i\ x 1 i x:将 a i a_i ai 修改为 x x x
  • 2   l   r   k 2\ l\ r\ k 2 l r k:询问在数组区间 [ l , r ] [l, r] [l,r] 内是否每个出现过的正整数的出现次数都是 k k k 的倍数。若是则输出 YES,若否则输出 NO

你会发现这个问题很怪异,询问区间出现过的数的出现次数是否为k的倍数。

显然,如果一个数的出现次数真的是 k k k 的倍数,那把这个数的权值加起来应该也是k的倍数。更具体地,如果全部数都满足是 k k k 的倍数,那区间和也应该是 k k k 的倍数。

看起来这就是个很不错的判定方法,然而随便卡一下就死了。于是我们决定将每个数随机映射一下再用这个做法。

考虑这个判定方法的错误率,若某一个数出现次数不是k的倍数,但是权值和是k的倍数(即 c n t i ∤ k , ( x ∗ c n t i ) ∣ k cnt_i \nmid k , (x*cnt_i) \mid k cntik,(xcnti)k),此时可以近似认为其概率为 x ∣ k x \mid k xk 的概率 ,则错误率约为 1 / k 1/k 1/k

k = 1 k=1 k=1 时直接判定正确,当 k > = 2 k>=2 k>=2 时,做三十组随机即可保证错误率低于 2 − 30 2^{-30} 230

P8819 [CSP-S 2022] 星战

n n n 个点 m m m 条边的有向图,每条边都有激活和失活两种状态,初始时均为激活状态。四种操作:

  1. 失活某条边;
  2. 失活以某个点为终点的所有边;
  3. 激活某条边;
  4. 激活以某个点为终点的所有边。

每次操作后回答,如果只考虑激活的边,是否满足:

  1. 所有的点出度均为 1 1 1
  2. 所有的点都满足,从这个点出发,可以走到一个环中。

玩一下两个条件,发现 2 2 2 包含于 1 1 1 ,很无语。

问题变成判所有点出度均为1。

直接看题会容易歪到根号分治去,但是其实 n = 5 e 5 n = 5e5 n=5e5

考虑直接维护这个二四操作还是相当地困难的,然而这是一个判定性问题,且描述相对简单,如果能想到Hash的话就大功告成了。

首先有个容易维护的必要条件,即总激活边数为n。接下来可以用的Hash的方法有很多,这里讲两种比较经典的。

  1. Sum Hash,随机一下权值,考虑加上每一条激活边指向的点的权值,若满足题目要求,则这个值应该等于 ∑ a i \sum a_i ai ,那么直接维护这个权值和就好了,因为转化为了入度的计算,二四操作也非常简单。可以多做几次Sum Hash以提高正确率(但做一次的正确率也足够高了)
  2. Xor Hash,会发现在满足必要条件的前提下,问题等价于所有点出度为奇数。那么转化为了一个奇偶性判定的问题,异或就可以派上用场了。我们考虑随机权值后,将偶出度的点权值异或起来,由于点权随机,可以认为存在偶出度点时,异或和不为 0 0 0,反之为 0 0 0。 于是维护偶出度的点权值异或和,只需要正确地初始化,并在每一次边的状态变化时异或一次出点权值即可。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值