逆元 专题

洛谷逆元板子题
exgcd,费马小定理,线性算法板子

逆元预处理

线性算法板子

	inv[0] = inv[1] = 1;
	for(int i = 2; i <= maxn - 1; ++i)// 一定要从2开始
		inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;

i n v [ i ] inv[i] inv[i] i i i m o d mod mod 取模下的逆元

阶乘逆元

如果再进行这个处理

	for(int i = 2; i <= maxn - 9; ++i)
		inv[i] = (inv[i] * inv[i-1]) % mod;

那么 i n v [ i ] inv[i] inv[i] 就变成了 i ! i! i! 的逆元

总结一下就是预处理阶乘和阶乘的逆元

f a c fac fac i n v inv inv 数组必须开 l o n g long long l o n g long long

	fac[0] = inv[0] = 1;
	fac[1] = inv[1] = 1;
	for(int i = 2; i <= maxn - 9; ++i)
		fac[i] = fac[i-1] * i % mod,
		inv[i] = (ll)(mod - mod / i) * inv[mod % i] % mod;
	for(int i = 1; i <= maxn - 9; ++i)
		inv[i] = inv[i-1] * inv[i] % mod;

然后我们就可以 O ( 1 ) O(1) O(1) 查询组合数

ll C(ll n, ll m){
	if(m > n) return 0ll;
	return fac[n] * inv[m] % mod * inv[n-m] % mod;
}

题目

题解 D

#include<bits/stdc++.h>
using namespace std;
#define ll long long

const ll mod = 1e9+7;
ll power(ll a, ll b)
{
    ll res = 1;
    while(b)
    {
        if(b & 1) res = res * a % mod;
        b >>= 1;
        a = a * a % mod;
    }
    return res;
}
ll inv(ll x)//求逆元
{
    return power(x, mod - 2);   //结合求逆元的博客  易懂    x的p-2次方就是 x的逆元
}
ll a[100010], b[100010];
int main()
{
    ll n, k, i, j;
    cin >> n;
    for(i = 0; i < n; i++)cin >> a[i];
    for(i = 0; i < n; i++)cin >> b[i];
    ll res = 1;
    for(i=0; i < n; i++)
    {
        res = res * (a[i] - b[i]) % mod * inv(a[i]) % mod;
    }
    cout << (mod + (1 - res)) % mod;// 1-res 是负数的话  +mod 变成正数  然后取模   (~浅显易懂)哈哈
    // 前边的计算 一直在 %mod   所以数据一直在 小于mod 的 范围内
}

求概率
仔细看样例,0%的时候样例1给的 1,而不是100
所以答案是 (100 - n)/100 * (100 - n)/ 100
所以用到了逆元

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 998244353;
ll n, m;
ll q_power(ll a, ll n)
{
	ll ans = 1;
	while(n)
	{
		if(n & 1) ans = (ans * a) % mod;
		n >>= 1;
		a = (a * a) % mod;
	}
	return ans;
}
int main()
{
	int t;
	cin >> t;
	while(t--)
	{
		cin >> n;
		if(!n) cout << 1 << endl;
		else if(n == 100) cout << 0 << endl;
		else 
		{
			long long ans = (100-n) * q_power(100, mod-2) % mod;
			cout << (ans * ans) % mod << endl;
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值