模数不超过 long long 范围时的快速乘
笔者的话:使用前请确保评测系统的long double严格为16B !
模数不在 int 范围内的乘法在 OI 中运用广泛,例如Millar-Rabin,Pollard-Rho等等。这样的乘法,直接乘惨遭 long long 溢出, WA 声一片。冒险运用 __int128 ,一朝事发,倾家荡产。误食 $O(\log P)$ 的龟速乘,人傻常数大, TLE 也无处申诉。这个时候, $O(1)$ 的快速乘就能派上用场。
快速乘运用真正的long double解决这样的一个问题:给定 $x,y,P$ 满足 $0\le x,y<P$ ,计算 $xy\bmod P$ 。这里 $P< 2^{63}$ 。注意 $P$ 不一定是质数。
首先分析取模, $xy\bmod P=xy-\lfloor\frac{xy}{P}\rfloor P=(xy-\lfloor\frac{xy}{P}\rfloor P) \bmod 2^{64}$ 。所以,算出 $\lfloor\frac{xy}{P}\rfloor$ 后可以巧妙地借助自然溢出计算左右两个乘法和中间的减法,得到该式对 $2^{64}$ 取模的结果,也就得到了该式。
于是我们只剩下了一个难点就是计算 $\lfloor\frac{xy}{P}\rfloor$ 。这肯定不能先乘再除,只能先除再乘再取整。考虑搬出16B 的 long double ,先除再乘。
既然运用了 long double ,无疑这会有精度误差。极端情况是 $\frac{x}{P}$ 的第一个有效位在小数点后第一位,那么 long double 从第六十五位开始出错,因此误差范围在 $(-2^{-64},2^{-64})$ ,乘 $y$ 之后就为 $(-\frac{1}{2},\frac{1}{2})$ 。运用常见技巧将其加上0.5L,误差范围变为 $(0,1)$ 。于是,取整时误差为 $0,1$ 之一,乘 $-P$ 以后,最终误差为 $0,-P$ 之一。也就是说,设答案为 $a$ ,最后的计算结果 $r$ 为 $a-P,a$ 之一。
由于 P 在 long long 内,所以当 $0\le r<P$ 时其为第二类,直接返回 $r$ ,否则为第一类,返回 $r-P$ ,就完成了快速乘计算。时间比较充裕的话直接返回 $(r+P)\bmod P$ 即可。
经实测,在笔者笔记本电脑上,开启O2进行1e8次此数据范围内的乘法运算,快速乘耗时 6.248s ,而龟速乘耗时 55.043s ,并且计算结果相同,足以见得快速乘的优越性。
附代码:
快速乘
typedef unsigned long long ll;
ll mul(ll x,ll y,ll P){ll z=x*y-(ll)((long double)x/P*y+0.5L)*P;return z<P?z:z+P;}
龟速乘
typedef unsigned long long ll;
ll mul(ll x,ll y,ll P){ll z=0;for(;y;(x<<=1)>=P&&(x-=P),y>>=1)y&1&&((z+=x)>=P&&(z-=P));return z;}
模数不超过 long long 范围时的快速乘的更多相关文章
- Easyui datagrid 设置内容超过单元格宽度时自动换行显示
datagrid 设置内容超过单元格宽度时自动换行显示 by:授客 QQ:1033553122 测试环境 jquery-easyui-1.5.3 问题描述 单元格内容超过单元格宽度不会自动化换行.如下 ...
- gvim写html代码时如何快速地跳转到一个标签的结束位置: 终极插件: matchit.vim
gvim写html代码时如何快速地跳转到一个标签的结束位置 参考这个vimrc的配置, 里面有一些 很好的东西, 配置很有用, 以前没有用到: http://www.cnblogs.com/wangj ...
- 如何固定OpenERP顶的主菜单,方便滚动至第二屏以及多屏时,快速切换主菜单
如何固定OpenERP顶的主菜单,方便滚动至第二屏以及多屏时,快速切换主菜单 作者:广州-步科,来自OpenERP应用群() 将“addons\web\static\src\css”目录下的“base ...
- m_Orchestrate learning system---二十七、修改时如何快速找到作用位置
m_Orchestrate learning system---二十七.修改时如何快速找到作用位置 一.总结 一句话总结:找人,找起作用的位置真的重要,找到就事半功倍了 加载页面的时候观察在f12的e ...
- 小记:Quartz 当 Job 执行时间超过触发间隔时间时所发生的情况
一个普通的 Job 实现如下: public class Job1 : IJob { public void Execute(IJobExecutionContext context) { Conso ...
- Redis持久化磁盘IO方式及其带来的问题 有Redis线上运维经验的人会发现Redis在物理内存使用比较多,但还没有超过实际物理内存总容量时就会发生不稳定甚至崩溃的问题,有人认为是基于快照方式持
转自:http://blog.csdn.net/kaosini/article/details/9176961 一.对Redis持久化的探讨与理解 redis是一个支持持久化的内存数据库,也就是 ...
- 解决git push时发现有超过100M的文件时,删除文件后,发现还是提交不上去的问题
我这里故意放了一个超过100M的文件 后续,git add ,git commit 然后,git push 此时会发现出现了错误.如果,我们再这里直接在文件系统中删除这个大的文件,然后再次提交,会发现 ...
- Vue:列表展开和收起(超过一定行数时显示‘查看更多’按钮)
前言:前端小白记录的一些小功能~ 公司开发中的小程序中有做任务签到的功能,这就涉及到了任务列表以及对任务列表的展开和收起功能,好了可以开始了,说多了就烦了 1.首先是css样式,因为设计稿上是超过两行 ...
- NodeJs使用Express框架开发时的快速调试方法
习惯了php开发,可以直接使用echo或者var_dump()将想要查看的变量结果输出到网页查看,非常的方便.但是使用express开发时,每次修改文件后,都需要使用npm start命令重启服务,然 ...
随机推荐
- Redis 深入
1.缓存更新 一般来说缓存的更新有两种情况: 先删除缓存,再更新数据库. 先更新数据库,再删除缓存. 这两种情况在业界,大家对其都有自己的看法.具体怎么使用还得看各自的取舍.当然肯定会有人问为什么要删 ...
- T-SQL——关于XML类型
目录 0. 将结果集转化为XML格式 1. 列值拼接为字符串 2. 字符串转换为列值 3. 一些说明 参考 志铭-2021年10月23日 10:43:21 0. 将结果集转化为XML格式 测试数据 I ...
- MySQL:基础语法-1
MySQL:基础语法-1 记录一下 MySQL 基础的一些语法,便于查询,该部分内容主要是参考:bilibili 上 黑马程序员 的课程而做的笔记,由于时间有点久了,课程地址忘记了 关于数据库的安装操 ...
- 【二食堂】Alpha - 测试报告
TextMarking Alpha阶段测试报告 前后端测试过程及结果 在Alpha阶段,测试工作紧跟后端开发进度,一下是我们所做的一些测试工作. 后端单元测试 测试代码可以在git仓库中查看,后端对所 ...
- 第四单元博客总结——暨OO课程总结
第四单元博客总结--暨OO课程总结 第四单元架构设计 第一次UML作业 简单陈述 第一次作业较为简单,只需要实现查询功能,并在查询的同时考虑到性能问题,即我简单的将每一次查询的结果以及递归的上层结果都 ...
- The entitlements specified in your application’s Code Signing Entitlements file do not match those s
今天给打包 TPshop IOS (搜豹商城) ipa文件 调试运行 xcode运行提示这个错误: The entitlements specified in your application's C ...
- (类)Program1.1
1 class MyClass: 2 3 i = 12345 4 5 def __init__(self): 6 self.data = "WOOWOWOWO" 7 8 def f ...
- SpringCloud 2020.0.4 系列之 JWT用户鉴权
1. 概述 老话说的好:善待他人就是善待自己,虽然可能有所付出,但也能得到应有的收获. 言归正传,之前我们聊了 Gateway 组件,今天来聊一下如何使用 JWT 技术给用户授权,以及如果在 Gate ...
- kubernetes常见日志采集问题和解决方案分析
传统日志与kubernetes日志对比 传统服务 目录固定 重启不会丢失 不用关注标准与错误日志输出 容器服务 节点不固定 重启服务会漂移 需要关注标准与错误日志输出 日志文件重启会丢失 日志目录不固 ...
- 数据代理Object.defineProperty()
数据代理: 通过一个对象代理对另一个对象中属性的操作(读/写) 数据代理 Object.defineProperty() Object.defineProperty() 方法会直接在一个对象上定义一个 ...