Codeforces Global Round 23 F. Kazaee(随机化哈希+线段树)

题目

长度为n(n<=3e5)的数组,q(q<=3e5)次操作,操作分两种,

1. 输入i x(x<=1e9),将ai改成x

2. 输入l r k(1<=k<=n),询问对于在[l,r]内出现的每种数,其在[l,r]内的出现次数是不是均为k的倍数

思路来源

gzchenben的讲解

jjleo的代码

题解

随机化哈希,人尽皆知典中典

k的倍数,区间每种数的出现次数很难维护,考虑概率&哈希

对于输入的ai,先将其哈希映射到另一个数上,然后考虑按二进制位拆,

如果对于二进制的每一位,其在[l,r]内的和都是k的倍数,我们就认为答案是Yes,

这样错误的概率,对于某一位来说,在k=2时,是1/2,

因为随机哈希,可能将两个二进制这一位原本不同的数,映射成相同了,

但是,控制位数足够多后,这样询问出错的概率就很低了,

考虑到3e5组样例,实际后台可能有100个case,3e8左右,所以30位≈1e9不一定行,

这里控制位数M在35-40左右即可

不被hack掉的tips

1. 哈希是完全随机的(如mt19937_64)

2. 对于不同的ai,哈希出来的数不重复

心得

mt19937_64用起来很方便,实际控制M=64保险,但M=35-40就够用了,1/(2^35)的概率很低了

放一个抄来的随机数生成的方法,主要这题需要尽可能保证每次gen的随机数不重复

update:unordered_map被卡了,赶紧改回map

int gen(){
	static int o=4354347;
	o=(1ll*o*1926
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值