首页 > 其他分享 >[数论]取模

[数论]取模

时间:2023-06-17 09:24:27浏览次数:21  
标签:取模 return 数论 res ll long int mod

Mod

一、long long 乘法取模

核心思想

用long double 估计商的取值,然后任它溢出,它的真实答案和它%\(2^{64}\)次方答案是一样的
\(x*y\)%\(m = x*y-\dfrac{x*y}{m}*m\)

代码

ll mul(ll x,ll y,ll m)
{
	x%=m;y%=m;
	ll d = ((long double)x*y/m);
	d = x*y-d*m;
	if(d>=m)d-=m;
	if(d<0)d+=m;
	return d;
}

二、分数取模(没有逆元的情况)

例题:求\(S=\sum_{i = 1}^{n}q^i \bmod p\)

很容易发现的等比求和,\(S = \dfrac{q*q^{n-1}}{q-1}\)

因为\(q-1\)和\(p\)不一定互质,因此可能不存在逆元
所以我们必须转化
\(S = \dfrac{q*q^{n-1}}{q-1}\)
两边同乘一个数不改变同余性质那么我们给两边同乘分母
\((q-1)S = q*q^{n-1} mod (p*(q-1))\)

现在用快速幂就能解决啦,最后\(S\)再除以\((q-1)\)就是答案了

代码

#include<bits/stdc++.h>
using namespace std;
typedef __int128 ll;
ll q,n,p;
ll ksm(ll a,ll b,ll p)
{
	ll ans = 1,base = a;
	while(b)
	{
		if(b&1)
		{
			ans = ans*base%p;
		}
		base = base*base%p;
		b>>=1;
	}
	return ans%p;
}


int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		long long x,y,z;
		cin>>x>>y>>z;
		q = x,n = y,p = z;
		p = p*(q-1);
		ll s = (ksm(q,n+1,p)-q)%p;
		s/=(q-1);
		cout<<(long long)s<<endl;
	}
	return 0;
}

三、组合数取模(基本)

例题:回答T组询问,输出\(C_{n}^{m} \bmod 10^9+7\)的值。

\(C_{n}^{m} = \dfrac{n!}{m!*(n-m)!}\)
\(\dfrac{a}{b} \bmod p\) ==> \(a \bmod p*(b \bmod p)^{-1}\)

  1. \(n!*(m!)^{-1}*(n-m)^{-1}\)

  2. \(inv[i] = (p-\dfrac{p}{i})*inv[p\)%\(i]\)%\(p\)

    代码

#include<bits/stdc++.h>
using namespace std;
const int N = 1e7+10;
const int mod = 1e9+7;
typedef long long ll;
ll fac[N],fnv[N];

ll ksm(ll a,ll b)
{
	ll ans = 1,base = a;
	while(b>0)
	{
		if(b&1)
		{
			ans *= base;
			ans %= mod;
		}
		base *= base;
		base%=mod;
		b>>=1;
	}
	return ans;
}

ll binom(int n,int m)
{
	if(m<0||m>n)return 0;
	return fac[n]*fnv[m]%mod*fnv[n-m]%mod;
}

int main()
{
	fac[0] = 1;
	for(int i = 1;i<=N;i++)
		fac[i] = fac[i-1]*i%mod;
	fnv[N] = ksm(fac[N],mod-2);
	for(int i = N;i>=1;i--)
		fnv[i-1] = fnv[i]*i%mod;
	assert(fnv[0]==1);
	int t;
	cin>>t;
	while(t--)
	{
		int a,b;
		cin>>a>>b;
		cout<<binom(a,b)<<endl;
	}
	return 0;
}

四、取模的封装

代码

typedef long long ll;
struct modular_arithmetic {
    const int mod = 998244353;
    int add(ll a, ll b) {
        return (a % mod + b % mod) % mod;
    }
    int mul(ll a, ll b) {
        return ((a % mod) * (b % mod)) % mod;
    }
    int pow(ll x, ll n) {
        if (n == 0) return 1;
        int res = pow(x, n / 2);
        res = mul(res, res);
        if (n % 2) res = mul(x, res);
        return res;
    }
    int inv(ll x) {
        return pow(x, mod - 2);
    }
    int div(ll a, ll b) {
        return mul(a, inv(b));
    }
};
modular_arithmetic mod;

标签:取模,return,数论,res,ll,long,int,mod
From: https://www.cnblogs.com/nannandbk/p/17487025.html

相关文章

  • [数论]组合数取模
    CombinatorialNumber一、组合数取模1:例题:回答T组询问,输出\(C_{n}^{m}\bmod10^9+7\)的值。\(C_{n}^{m}=\dfrac{n!}{m!*(n-m)!}\)\(\dfrac{a}{b}\bmodp\)==>\(a\bmodp*(b\bmodp)^{-1}\)即\(n!*(m!)^{-1}*(n-m)^{-1}\)\(inv[i]=(p-\dfrac{p}{i})......
  • [数论]Divisor and Gcd
    DivisorandGcd1、算术基本定理:n的质因数分解唯一一些常见结论:1.素数无限2.\(\lim_{n\rightarrow+\infty}n\prod\dfrac{n}{\frac{n}{\ln{n}}}\)(Π(n)表示<=n素数的个数)————即n以下素数个数大约是\(\frac{n}{\ln(n)}\)级别的3.\(Pn=O(nlogn)\)级别的(Pn表示素数)......
  • [数论]中国剩余定理CRT
    ChineseRemainderTheorem\(x≡ai(modmi)\)中国剩余定理CRT1.定义Th.给出一元线性同余线性方程组\(x≡a1\bmodm1\)\(x≡a2\bmodm2\)...\(x≡an\bmodmn\)定理指出假设素数\(m1,m2...mn\)两两互素,对任意的整数\(a1,a2...an\)上述方程有解,并且可以通过如下......
  • [数论]素数筛和整数分块
    PrimesievingandIntegerblocking一、Primenumbersievemethod1.埃氏筛O(nloglogn)从2开始,2是质数,那么2的倍数:4、6、8、10、12、14、16...肯定不是质数3是质数,那么3的倍数:6、9、12、15、18、21.....肯定不是质数4已经被筛去了(即被置为false),不是质数,那么4的倍数肯定......
  • 高效的二进制取模算法
    限制必须是长度必须是2的指数直接取指数的低位长度算法演示长度为80b000(0)0b001(1)0b010(2)0b011(3)0b100(4)0b101(5)0b110(6)0b11(7)13二进制0x110113mod8=55的二进制1012^3=8直接取0x1101后三位101使用场景布谷鸟过滤器还有一种就......
  • (数论)判断素数(朴素,根号,埃氏筛,欧拉筛线性筛)
    //最基本求一个素数(on),(osqrt(n))#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;cin>>n;for(inti=2;i<n;i++)//o(n)if(n%i==0){cout<<"no";return0;}for(i......
  • [数论]GCD&LCM&欧拉函——推柿子+例题
    GCD&LCM&欧拉函——推柿子一、\(\sum_{i=1}^{n}[\gcd(i,n)=d]\)\(\sum_{i=1}^{n}[\gcd(i,n)=d]\)\(=\sum_{i=1}^{\frac{n}{d}}[\gcd(i,\frac{n}{d})=1]\)\(=\phi(\frac{n}{d})\)二、\(\sum_{i=1}^{n}\gcd(i,n)\)\(\sum_{i=1}^{n}\gcd(i,......
  • 数论基础
    求和符号的定义为了简化形如\(a_1+a_2+...+a_n\)这样求\(n\)个数的和的表述,引入求和符号\(\sum\),将上式重表述为\(\sum\limits_{i=1}^na_i\)。其中,\(i\)被称为指标变量,取值为从\(1\)到\(n\)的整数,\(a_i\)为关于\(i\)的函数。求和符号的性质定理1:\(\sum\limits_......
  • 【学习笔记】(14) 初等数论(一)
    1.【最大公约数(GCD)和最小公倍数(LCM)】【基本性质、定理】\(\largegcd(a,b)=gcd(b,a−b)(a>b)\)\(\largegcd(a,b)=gcd(b,a\)\(\largemod\)\(b)\)\(\largegcd(a,b)\)\(\largelcm(a,b)=ab\)【推导结论】\(\largek|gcd(a,b)⟺k|a\)且\(k|b\)\(\larg......
  • 数论-裴蜀定理-扩展欧几里得算法
    裴蜀定理对于任意的整数a、b,都存在一对整数x、y(注意x和y可以是负整数),使得\(ax+by=gcd(a,b)\)成立。或者可以这样描述:对方程\(ax+by=c,(a,b,c∈Z)\),只有满足\(gcd(a,b)|c\)(即a和b的最大公约数可以整除c),方程才有整数解。扩展欧几里得算法的证明已知\(gcd(a,b)=gcd(b,a\%b)\)......