ACM number theory board

It's not finished yet.

Recommended blog:

[summary] number theory is related to combinatorial counting Mathematics (theorem & proof & board)
[summary] other miscellaneous mathematics related (theorem & proof & board)
Summary] mathematical correlation of polynomials (theorem & proof & board)
[exploration] various primary number theory algorithms in OI are related

Catalog:

Slow & Fast & slow
Fast power & matrix fast power & matrix fast power & matrix fast power
GCDGCDGCD
EXGCDEXGCDEXGCD
Multiplication inverse element multiplication inverse element multiplication inverse element
RCTRCTRCT
EXRCTEXRCTEXRCT

Board:

Slow ride

In case of large modulus, prevent long long long long.

ll qmul(ll a,ll b,ll p)
{
    ll ans=0;
    while(b)
    {
        if(b&1)
            ans=(ans+a)%p;
        a<<=1;
        a%=p;
        b>>=1;
    }
    return ans;
}

Fast ride
The purpose is the same as above, but the time complexity is O(1)O(1)O(1). (take charge of the accuracy of the output ~)

ll fmul(ll a,ll b,ll p)
{
    return (a*b-(ll)((long double)a*b/p)*p+p)%p;
}

Counting

ll qpow(ll a,ll b)
{
    ll t1=a,t2=1;
    while(b)
    {
        if(b&1)
            t2=t2*t1%p;
        t1=t1*t1%p;
        b>>=1;
    }
    return t2;
}

Matrix fast power
The principle is the same as the fast power, only need to construct the matrix and realize the matrix multiplication, give an example.

struct Matrix
{
	ll t[3][3];
	Matrix()
	{
		t[0][0]=t[0][1]=t[2][0]=t[2][2]=1;
		t[1][0]=2;
		t[0][2]=t[1][1]=t[1][2]=t[2][1]=0;
	}
};

Matrix mul(Matrix a,Matrix b)
{
	Matrix c;
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
			c.t[i][j]=0;
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
			for(int k=0;k<3;k++)
				c.t[i][j]=(c.t[i][j]+a.t[i][k]*b.t[k][j])%m;
	return c;
}

Matrix qpow(ll b)
{
	Matrix t1,t2;
	for(int i=0;i<3;i++)
		for(int j=0;j<3;j++)
		{
			t1.t[i][j]=(i==j?1:0);
		}
	while(b>0)
	{
		if(b&1)
			t1=mul(t1,t2);
		t2=mul(t2,t2);
		b>>=1;
	}
	return t1;
}

GCDGCDGCD

int gcd(int a, int b) 
{
     return b == 0 ? a : gcd(b, a%b);
} 

EXGCDEXGCDEXGCD

int exgcd(int a, int b, int &x, int &y) 
{
    if (b == 0) 
    {
        x = 1; y = 0;
        return a;
    }
    int c = exgcd(b, a%b, x, y);
    int t = x;
    x = y;
    y = t-a/b*y;
    return c;
}

Tip: a*x+b*y=gcd(a,b)tip: a*x+b*y=gcd(a,b)tip: a * x+b * y=gcd(a,b). When a, pa, pa, p are mutually prime, if you want to require the multiplicative inverse of aaa module ppp, you only need to call exgcd (a, p, x, y) exgcd (a, p, x, y). The answer is xxx. (xxx may be a negative number, please pay attention to it.)

Multiplicative inverse element

The common solution of the inverse element of multiplication is as above. Here, only the linear algorithm of the inverse element is mentioned.

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

const int maxn=3e6+5;

int n,p;
int inv[maxn]; //inv[i] represents the multiplicative inverse of i-module p

void work()//To find out the inverse element of multiplication of all 1-n numbers in the sense of modulo p, it is necessary to ensure that P is a prime number and N < p
{
    inv[1]=1;
    for(int i=2;i<=n;i++)
    {
        inv[i]=(ll)-(p/i)*inv[p%i]%p;
        if(inv[i]<0)
            inv[i]+=p;
    }
}

int main()
{
    scanf("%d %d",&n,&p);
    work();
    for(int i=1;i<=n;i++)
        printf("%d\n",inv[i]);
    return 0;
}

RCTRCTRCT

ll qmul(ll a,ll b,ll p)
{
    ll ans=0;
    while(b)
    {
        if(b&1)
            ans=(ans+a)%p;
        a<<=1;
        a%=p;
        b>>=1;
    }
    return ans;
}

ll fmul(ll a,ll b,ll p)
{
    return (a*b-(ll)((long double)a*b/p)*p+p)%p;
}

ll exgcd(ll a,ll b,ll &x,ll &y)
{
    if(b==0)
    {
        x=1,y=0;
        return a;
    }
    ll c=exgcd(b,a%b,x,y);
    ll t=x;
    x=y;
    y=t-a/b*y;
    return c;
}

ll inv(ll a,ll p)// Finding the multiplication inverse element of a%p
{
    ll x,y;
    exgcd(a,p,x,y);
    return (x%p+p)%p;
}

ll RCT()
{
    ll ans=0,M=1;
    for(int i=1;i<=n;i++)
        M*=m[i];
    for(int i=1;i<=n;i++)
    {
        ll tmp=M/m[i];
        ans=(ans+fmul(fmul(a[i],tmp,M),inv(tmp,m[i]),M))%M;
    }
    return (ans+M)%M;
}

EXRCTEXRCTEXRCT

ll EXRCT()
{
    ll ans=a[1],M=m[1];
    ll x,y,gcd;
    for(int i=2;i<=n;i++)
    {
        gcd=exgcd(M,m[i],x,y); // M * x + m[i] * y = gcd(M,m[i])
        ll t1=((a[i]-ans)%m[i]+m[i])%m[i];
        ll t2=m[i]/gcd;
        if(t1%gcd!=0)
            return -1; //unsolvable
        x=fmul(x,t1/gcd,t2);
        ans+=x*M;
        M*=t2;
        ans=(ans%M+M)%M;
    }
    return ans;

}
614 original articles published, praised 23, visited 30000+
His message board follow

Posted on Mon, 13 Jan 2020 07:11:22 -0500 by Gafaddict