◆学时·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

应该还有很多,一下子记不起来了 (`・ω・´)


□除了做题好像没有什么用了□

给出一个矩阵,在它的左下角剪去一个矩阵(只是一个角,保证剩余图形不是一个矩形),从左上角开始,可以向下或向右移动一个单位。

求从左上角到右下角的路径方案总数,答案模(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◆ 逆元法的更多相关文章

  1. 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$要求 ...

  2. Chat Group gym101775A(逆元,组合数)

    传送门:Chat Group(gym101775A) 题意:一个宿舍中又n个人,最少k(k >= 3)个人就可以建一个讨论组,问最多可以建多少个不同的讨论组. 思路:求组合数的和,因为涉及除法取 ...

  3. springMVC文件上传与下载(六)

    1..文件上传 在springmvc.xml中配置文件上传解析器 <!-- 上传图片配置实现类,id必须为这个 --> <bean id="multipartResolve ...

  4. 洛谷 - P2051 - 中国象棋 - 简单dp

    https://www.luogu.org/problemnew/show/P2051 一点都不简单的简单dp. 还是从旧行转移到新行,而不是考虑新行从哪些旧行转移吧. #include<bit ...

  5. E20170516-gg

    accelerator  n. 加速器;油门 oscillator  n. 振荡器; 振子; oscillate  vt. 使振荡,使振动  vi. 持续周期性地摆动; frame  n. 框架; 边 ...

  6. 如何使用和关闭onbeforeunload 默认的浏览器弹窗事件

    Onunload,onbeforeunload都是在刷新或关闭时调用,可以在<script>脚本中通过 window.onunload来指定或者在<body>里指定.区别在于o ...

  7. OpenCASCADE Root-Finding Algorithm

    OpenCASCADE Root-Finding Algorithm eryar@163.com Abstract. A root-finding algorithm is a numerical m ...

  8. 基本数据类型-列表_元组_字典_day4

    一.列表(list)书写格式:[] #通过list类创建的 li = [1, 12, 9, ", 10, ],"庞麦郎"], "ales", True ...

  9. LeetCode17 Letter Combinations of a Phone Number

    题意: Given a digit string, return all possible letter combinations that the number could represent. A ...

随机推荐

  1. IPM的修炼之路

    总结了一下最近一年半来看到的产品经理方面的素养资料. 产品经理: 必备素质:市场洞察,抽象概括,创新想象,心思细腻,热爱产品,具备一定的企业家精神等. 是通才:市场,项目,设计,管理,用户,统计,心理 ...

  2. pat1068. Find More Coins (30)

    1068. Find More Coins (30) 时间限制 150 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Eva l ...

  3. 亲测SQLServer的最大连接数

    很多做架构设计.程序开发.运维.技术管理的朋友可能或多或少有这样的困惑: SQLServer到底支持多少连接数的并发? SQLServer是否可以满足现有的应用吗? 现有的技术架构支持多少连接数的并发 ...

  4. Fedora 安装 phpMyAdmin(可能只有自己看得懂)

    yum groupinstall "Development Tools" yum install php-mysqli php-mbstring php-mcrypt yum in ...

  5. vue的ajax

    vue的ajax常见的有两种 ,一种是 vue-resource,一种是axios vue-resource: 是vue的插件,非官方库, vue1.x 使用广泛 如何使用: 先在vue的脚本架上安装 ...

  6. SQLSERVER 2008 R2 事务日志已满

    方法一: USE [master] GO ALTER DATABASE DNName SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE DNName ...

  7. appium-python-api中文文档

    来自https://wenku.baidu.com/view/533603ce581b6bd97e19eaa1.html mark,同时提供给需要使用python写脚本的童鞋们

  8. PyYAML使用

    install yum -y install PyYAML document http://www.showyounger.com/show/101586.html http://pyyaml.org ...

  9. Linux vi 常用指令总结

    本文根据笔者,日常常用的linux下的vi指令,进行说明 一.基本操作 1.vi 文件名 进入vi 的“命令行模式”,此模式无法编辑,只能查看 需要按下键盘的“i”键,进入“编辑模式”,才能进行文件的 ...

  10. 使用mongoDB时错误解决

    接触mongodb遇到的错误,记录下来,后续遇到问题,会持续更新 为了让mongodb更直观,在windows使用了NoSQL Manager for MongoDB作为连接工具 1.在连接数据库时遇 ...