首页 > 其他分享 >由AtCoder_ABC357D引发的除法同余学习

由AtCoder_ABC357D引发的除法同余学习

时间:2024-06-11 13:57:03浏览次数:8  
标签:AtCoder ll long MOD ABC357D 同余 inv mod

鉴于最近的Atcoder周赛又出现除法求余,下定决心学习逆元相关内容

同余概述

定义

同余定义:若a和b是整数,且m | (a - b),则称a和b模m同余。即两者除以m得到的余数相同。

剩余系:一个模m完全剩余系是一个整数集合,任何一个整数恰好与该集合中的一个元素模m同余。例如0,1,...,m-1的集合是模m完全剩余系。

求解同余方程\(ax\equiv b(mod\ m)\)需要用到逆

逆的概念

给定整数a,并且满足\(gcd(a,m) = 1\),称 \(a * x \equiv 1 (mod \ m)\)的一个解为a模m的逆,记为\(a^{-1}\)

即a的x倍模m的结果等于1,对应的x记为a模m的逆


《算法竞赛》书上的逆元部分太难了,直接跑路,选择左神视频速成除法同余

除法同余

求\((a/ b) mod \ MOD\)的结果

需要满足的条件
  1. \(a / b\)在每次存在除法的时候都可以整除
  2. 保证MOD是质数以满足费马小定理
  3. 保证b和MOD的最大公约数为1
除法同余的结论
  1. 求\(\frac{1}{b}\)关于MOD的同余数,也就是b的逆元,将除法同余转化为乘法同余
  2. 使用费马小定理求b的逆元,\(inv[b] = b^{MOD-2}\ \% \ MOD\)
  3. 得到对应的结果 \((a/ b) \% MOD = ((a \% MOD) * inv[b])\%MOD\)
除法同余所用到的快速幂
define ll long long;
ll fast_pow(ll x, ll y, int m) {
	ll res = 1;
	while (y) {
		if (y & 1) res *= x, res %= m;
		x = (x * x) % m;
		y >>= 1;
	}
	return res;
}
long long mod_inverse(long long a, long long mod) {
	return fast_pow(a, mod - 2, mod);
}
该题解的起源abc357D的示例代码
#include<bits/stdc++.h>  
using namespace std;  
typedef long long ll;  
const int mod = 998244353;  
ll n;  
ll fast_pow(ll b, ll p, ll m) {  
    ll res = 1;  
    while (p) {  
        if (p & 1) res *= b, res %= m;  
        p >>= 1;  
        b = (b * b) % m;  
    }  
    return res;  
}  
ll cacu_inv(ll a, ll m) {  
    return fast_pow(a, m - 2, m);  
}  
int main() {  
    cin >> n;  
    int w = 0;  
    ll tmp = n;  
    while (tmp) {  
        w++;  
        tmp /= 10;  
    }  
    ll base = fast_pow(10, w, mod);  
    ll res = ((fast_pow(base, n, mod)+ mod - 1) % mod) * cacu_inv((base + mod - 1) % mod, mod)  % mod;  
    //注意n的范围[1,1e18]同样需要除余  
    cout << (res * (n % mod)) % mod;  
    return 0;  
}

连续数字逆元的线性递推

例题P3811

在\(\% p\)的意义下,求\(1,2,3,...n\)中每个数的逆元
\(inv[1] = 1\)
\(inv[i] = (int)(p - (long)inv[p \% i] * (p / i)\%p\)

连续阶乘逆元的线性递推

求组合数的逆元

先求\(n!\)乘法同余的结果,假设为\(a\),然后求\(a\)的逆元,假设为\(b\)
\(inv[n] = b\)
\(inv[i] = ((long)(i + 1) * inv[i + 1])\% MOD\)

标签:AtCoder,ll,long,MOD,ABC357D,同余,inv,mod
From: https://www.cnblogs.com/tanch25/p/18241907

相关文章

  • Atcoder357D题解(求解等比数列求和公式的推导)
    解题思路设连接之后的N等于Nlast,w=10^(N在10进制下的长度,例如N=5,那么w=10)Nlast=N+N*w+N*(w^2)+N*(w^3)+.....+N*(w^n)举个例子N=5,因为510进制的长度是1,所以w=10,那么Nlast=5+5*10(w)^1+5*10(w)^2+5*10(w)^3+......
  • Atcoder357 D(逆元和快速幂)
    Atcoder357DD题意就是求给定一个数n的连续n个n相拼接,求最后的数\(mod998244353\)的值。我们假设n的长度为len,那么n个n相拼接可以看成n*(\(10^{len^0}\)+\(10^{len^1}\)+....+\(10^{len^{n-1}}\))。那个就可以利用高中等比数列的知识求出公式(\(n*(10^{len^n}-1\))/(\(10^{len}......
  • AtCoder Beginner Contest 357
    ABC357总结AtCoderBeginnerContest357A-SanitizeHands翻译有一瓶消毒剂,正好可以消毒\(M\)双手。\(N\)名外星人陆续前来消毒双手。\(i\)个外星人(\(1\leqi\leqN\))有\(H_i\)只手,想把所有的手都消毒一次。请计算有多少个外星人可以给所有的手消毒。在这里,即......
  • SuntoryProgrammingContest2024(AtCoder Beginner Contest 357)
    A-SanitizeHands题意:给定一个序列和m,问m按顺序减去这个序列,m>=0情况下最多能减多少个数思路:前缀和+prev(upper_bound())总结:disinfectan(消毒ji),disinfect(消毒,杀毒),aliens(外星人),voidsolve(){ intn,m; cin>>n>>m; vector<int>a(n); for(inti=......
  • ATcoder ABC 351 补题记录(A~F)
    A按照顺序直接模拟即可。#pragmaGCCoptimize(3)#include<bits/stdc++.h>#defineintlonglong#definepbpush_back#defineememplace_back#defineF(i,x,y)for(inti=x;i<=y;i++)#defineG(i,x,y)for(inti=x;i>=y;i--)#defineW(G,i,x)for(auto&i:G[x......
  • atcoder ABC 353-A题详解
    atcoderABC353-A题详解ProblemStatementThereareNbuildingsalignedinarow.Thei-thbuildingfromthelefthasaheightofHi.Determineifthereisabuildingtallerthanthefirstonefromtheleft.Ifsuchabuildingexists,findtheposition......
  • Atcoder Beginner Contest 355
    A-WhoAtetheCake?#include<bits/stdc++.h>usingnamespacestd;usingi64=longlong;intmain(){ ios::sync_with_stdio(false),cin.tie(nullptr); intA,B; cin>>A>>B; if(A==B)cout<<-1; elsecout<<6-A......
  • atcoder ABC 356-B题详解
    atcoderABC356-B题详解ProblemStatementTakahashiishealth-consciousandconcernedaboutwhetherheisgettingenoughofMtypesofnutrientsfromhisdiet.Forthei-thnutrient,hisgoalistotakeatleastAi​unitsperday.Today,heateNfoods......
  • AtCoder Beginner Contest 356
    Contest从比赛开始第三分钟开始记:00:00~00:02:A题。00:02~00:07:B题。00:07~00:16:C题。00:16~00:43:D题。00:43~01:02:E题。01:02~结束:摆烂。A-SubsegmentReverse给定\(n,l,r\)。输出将序列\(A=(1,2,\dots,n)\)中\([l,r]\)翻转后的样......
  • AtCoder Beginner Contest 356
    A-SubsegmentReverse(abc356A)题目大意给定一个\(1,2,3,...,n\)的排列\(a\),给定两个数\(l,r\),左右颠倒\(a[l..r]\)。输出。解题思路按照题意模拟即可。神奇的代码#include<bits/stdc++.h>usingnamespacestd;usingLL=longlong;intmain(void){ios::......