【学时总结】◆学时·V◆ 逆元法
◆学时·V◆ 逆元法
□算法概述□
逆元运算是模运算中的一个技巧,一般用于解决模运算的除法问题。
模运算对于加、减、乘是有封闭性的,即 (a±b)%m=a%m±b%m,以及 (a×b)%m=a%m×b%m。但是对于除法运算不满足这样的规律。因此在处理两个大数相除的商模一个数会遇到困难。这时候需要逆元。
逆元的定义如下:
若 ab≡1 (mod m),则对于模m,a、b互为逆元
那么就有 b≡a-1。这就可以发挥作用了—— p/a%m=p*b%m,也就是除以一个数N再取模,等于乘上N的逆元再取模。
我们用 a-1 表示a的逆元。
□逆元的计算□
一眼望过去全是数学……
- 费马小定理
当p为质数且a不为p的倍数时,满足 ap-1≡1 (mod p),所以有 a*ap-2≡1,也就是说 a、ap-2 互为逆元。
很简单是不是,但别忘了这只是p是质数的时候才能用!OI中经常会出现“答案模(1e9+7)”,很幸运,(1e9+7)就是一个很有用的质数!
- 算法I
其实许多算法没有想象的这么难……
对于模数m,一定有整数(一般定义是正整数)a、p、r 满足 m=pa+r ,可以看成“被除数=商*除数+余数”。
可以得到:ap+r≡0(mod m)→-ap≡r(mod m)→-pr-1≡a-1 ,也就是 商与 余数的逆元 的积 的相反数 是 除数的逆元。
当然大家都知道当 r=0 ,即 m被p整除时,r-1 是不成立的!
而这个算法最玄学的地方在与 余数是一定小于除数的。这意味着什么呢?
—— 你在递推计算除数的逆元时,应该已经把余数的逆元算出来了。
- 算法II
不要慌……下面是一个递归式:
n-1=(n-1)!·(n!)-1
首先是一个不需要解释的小式子 n·[(n-1)!/n!]≡1。就很容易得到n的逆元就是(n-1)!/n!,稍微换一下,(n-1)!*(n!)-1。
应该还有很多,一下子记不起来了 (`・ω・´)
□除了做题好像没有什么用了□
- 传送门 ¦ARC 059 C¦
- 【翻译】
给出一个矩阵,在它的左下角剪去一个矩阵(只是一个角,保证剩余图形不是一个矩形),从左上角开始,可以向下或向右移动一个单位。
求从左上角到右下角的路径方案总数,答案模(1e9+7) (没错,就是这个不可描述的质数)
- 【解析】
很容易得到从A(p,q)到B(m,n),则纵向移动 |n-q|,横向移动 |m-p| ,总共移动 |n-q|+|m-p| 。因此,如果我们把移动步骤表示为一个串,则一定有 |m-p| 个步骤是横向移动的。那么A到B的方案总数为 C(|m-p|,|m-p|+|n-q|)。
假设现在没有剪去角,则矩形(r,c)从左上到右下方案总数为 C(r+c,r) = A。
我们还可以算出从剪去矩阵内的点出发,到达右下角的方案数B,由于答案与这些方案是补集,所以全集A减去子集B就是答案了。
但是计算组合数时就遇到了困难,此时就需要逆元。可以用初始化直接解决,当然需要使用快速幂。(计算逆元的函数是Pre,快速幂函数是PowMod)
- 【源代码】
/*Lucky_Glass*/
#include<cstdio>
#include<algorithm>
using namespace std;
#define MO 1000000007
#define MAXN 200005
#define LL long long
LL inv[MAXN],s[MAXN];
int n;
LL PowMod(LL a,int b)
{
LL ret=;
while(b)
{
if(b&) ret=ret*a%MO;
a=a*a%MO;
b>>=;
}
return ret;
}
void Pre()
{
s[]=;
for(int i=; i<=n; i++)
s[i]=s[i-]*i%MO;
inv[]=;
inv[n]=PowMod(s[n],MO-);
for(int i=n-; i>; i--)
inv[i]=inv[i+]*(i+)%MO;
}
LL C(int a,int b){if(a<||b<) return ;return s[a]*inv[b]%MO*inv[a-b]%MO;}
int main()
{
int h,w,A,B;
scanf("%d%d%d%d",&h,&w,&A,&B);
n=h+w-;
Pre();
LL ans=C(h+w-,h-);
for(int i=; i<=B; i++)
{
ans-=C(h-A+i-,h-A-)*C(A-+w-i,A-)%MO;
ans=(ans%MO+MO)%MO;
}
printf("%lld\n",ans);
}
The End
Thanks for reading!
- Lucky_Glass
【学时总结】◆学时·V◆ 逆元法的更多相关文章
- MT【330】u,v,w法
已知$a^2+b^2+c^2=1$求$abc(a+b+c)$的最小值.(2018辽宁预赛解答压轴题) 不妨设$a+b+c=3u,ab+bc+ca=3v^2,abc=w^3$,令$u^2=tv^2$要求 ...
- Chat Group gym101775A(逆元,组合数)
传送门:Chat Group(gym101775A) 题意:一个宿舍中又n个人,最少k(k >= 3)个人就可以建一个讨论组,问最多可以建多少个不同的讨论组. 思路:求组合数的和,因为涉及除法取 ...
- springMVC文件上传与下载(六)
1..文件上传 在springmvc.xml中配置文件上传解析器 <!-- 上传图片配置实现类,id必须为这个 --> <bean id="multipartResolve ...
- 洛谷 - P2051 - 中国象棋 - 简单dp
https://www.luogu.org/problemnew/show/P2051 一点都不简单的简单dp. 还是从旧行转移到新行,而不是考虑新行从哪些旧行转移吧. #include<bit ...
- E20170516-gg
accelerator n. 加速器;油门 oscillator n. 振荡器; 振子; oscillate vt. 使振荡,使振动 vi. 持续周期性地摆动; frame n. 框架; 边 ...
- 如何使用和关闭onbeforeunload 默认的浏览器弹窗事件
Onunload,onbeforeunload都是在刷新或关闭时调用,可以在<script>脚本中通过 window.onunload来指定或者在<body>里指定.区别在于o ...
- OpenCASCADE Root-Finding Algorithm
OpenCASCADE Root-Finding Algorithm eryar@163.com Abstract. A root-finding algorithm is a numerical m ...
- 基本数据类型-列表_元组_字典_day4
一.列表(list)书写格式:[] #通过list类创建的 li = [1, 12, 9, ", 10, ],"庞麦郎"], "ales", True ...
- LeetCode17 Letter Combinations of a Phone Number
题意: Given a digit string, return all possible letter combinations that the number could represent. A ...
随机推荐
- vue-cli生成的重要代码详解
安装好vue-cli之后,我们可以在package.json中看到下面所示: { // 项目名称 "name": "myvue", // 项目版本 " ...
- mysql操作命令梳理(3)-pager
在mysql日常操作中,妙用pager设置显示方式,可以大大提高工作效率.比如select出来的结果集超过几个屏幕,那么前面的结果一晃而过无法看到,这时候使用pager可以设置调用os的more或者l ...
- 重启部署在Linux系统下的tomcat服务
重启部署在Linux系统下的tomcat服务具体的操作步骤: 1.在Winscp上建立连接,输入用户和密码,这个密码一般是看不到的: 2.查看服务:ps -ef | gerp Java 注意在 ...
- 初步学习XML的基本代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- Hibernate课程 初探一对多映射2-7 测试-修改和删除学生信息
package com.ddwei.entity; import java.util.Set; import org.hibernate.Session; import org.hibernate.T ...
- vue-计算属性不能直接修改
今天在开发的时候,遇到一个问题: 数据如下: data(){ queryCouponList : [] // 通过接口,会更新该数据 } , computed : { couponList () { ...
- 在使用angular和swiper插件中的一些问题
在使用angular获取swiper图片的时候swiper就不会轮播. 解决方法: 1.使用计时器的方法,不是最优 settimeOut(function(){ mySwiper = new Swip ...
- Object in Java same as pointer
到目前为止,读者应对对象的“传递”有了一个较为深刻的认识,记住实际传递的只是一个句柄. 然而准确地说,Java是有指针的!事实上,Java中每个对象(除基本数据类型以外)的标识符都属于指针的一种.但它 ...
- 爆料!如何在Visual Studio 2017上体验五星级云服务
2017 年 3 月初,号称宇宙最强 IDE 之一的 Visual Studio 发布了最新的 2017 版本,遥想自己使用 VC++ 6.0 的当年,看着现在已然稀疏的头发,真是一入 IT 似海深, ...
- SQL中的聚合函数
聚合函数是对一组值执行计算并返回单一的值的函数,它经常与SELECT语句的GROUP BY子句一同使用,SQL SERVER 中具体的聚合函数如下:1. AVG 返回指定组中的平均值,空值被忽略. 例 ...