【NOI 2016模拟6.16】gene
2016-06-17 15:52
85 查看
题目描述
你有n个数{a1,⋯,an},以及m个数{b1,⋯,bm}对于任意一个ai,你可以任意选择任意多个abii乘起来对p取模,得到若干个数。
问所有这样子得到的数的并集大小。
n≤104,m≤105,1<p≤109,且p是个质数。
分析
首先a−bji是会被取到的,只需要取循环节的上一个就可以了。那么根据裴蜀定理,∀x∈[0,p−1),(b0,b1,⋯,bm,p−1)|x都可以被取到。
考虑到如此多个ai取并集不好做,那么求出离散对数以后,这个底数都会变成原根。问题就放到指数上了。
也就是说,我们记(ind(ai),b1,⋯,bm,p−1)=ci
考虑怎么计算这个ci。根据最大公约数的性质,这个东西等价于(ind(ai),(b1,⋯,bm,p−1))
ind(x)可以用离散对数算出来,但是考虑到这里我们需要求它和别的东西的最大公约数,我们没必要真的算出离散对数。
考虑x的阶ord(x),根据定义,ind(x)ord(x)≡0(modφ(p)),也就是说ind(x)=kφ(p)ord(x),且ord(x)与k互质。
考虑费马小定理aφ(p)≡1(modp),那么ord(x)必定是φ(p)的约数。
下证(ind(x),φ(p))=(φ(p)ord(x),φ(p))=φ(p)ord(x)
左式可以如下变换。
(ind(x),φ(p))=(ind(x)ord(x),ord(x)φ(p))ord(x)=(kφ(p),ord(x)φ(p))ord(x)=φ(p)(k,ord(x))ord(x)
由于(k,ord(x))=1,故左式等于右式。
有了这个以后,我们就可以在这个问题里将阶来取代离散对数起到相同的作用。
之后的问题就是给定n个ci,问有点多少个数至少是一个ci的倍数。
形式化地说,我们需要统计有多少个x,满足
x∈[0,φ(p)),∃i,ci|x
又因为ci|n,故ci|(n,x)
那么我们就可以枚举最大公约数,剩下的式子就是
∑d=1n[∃i,ci|d]φ(nd)
时间复杂度O(mlogbi+σ0(p)nlogp+nlnn)
空间复杂度O(n)
相关文章推荐
- 谷歌的秘诀你学得会
- Android-屏幕适配方案【占坑中】
- mac下解决Android Studio Gradle Build Running 特别慢的问题
- java中非对称加密(RSA)的使用
- android双击图片放大,放大拖动的简单功能
- Linux系统调用的实现机制分析
- 解析Lua中的全局环境、包、模块组织结构
- 华为OJ平台——首次不重复字符
- 剪枝+再训练:稀疏化DeepID2
- 垃圾回收
- java IO
- springRest+cross跨域支持
- Linux指令学习(centos6.5)之rpm 指令
- CentOS6.5下SNMP安装
- @Query----------------springMVC
- Java对象锁和类锁全面解析(多线程synchronized关键字)
- 《塔防类手游开发教程》 第九节 怪物加入血槽以及金币数值
- CentOS6.5下SNMP安装
- python实现文本文件转二进制文件(二进制序列化)
- Linux(Centos、Debian)之安装Java JDK及注意事项(转)