ACM模板

快速幂

ll pow_mod(ll x,ll n,ll mod){ll res=1;while(n){if(n&1)res=res*x%mod;x=x*x%mod;n>>=1;}return res;}//xµÄn´Î·½mod
template<typename T>void read(T &res){bool flag=false;char ch;while(!isdigit(ch=getchar()))(ch=='-')&&(flag=true);
for(res=ch-48;isdigit(ch=getchar());res=(res<<1)+(res<<3)+ch - 48);flag&&(res=-res);}
View Code

矩阵快速幂

const int MAXN = 10;
#define int long long
#define ll long long
struct Matrix
{
    ll mat[MAXN][MAXN];
};
Matrix P; 
Matrix I; //单位矩阵
Matrix Mul_Matrix(Matrix a, Matrix b , ll mod)
{
    Matrix c;
    for(int i = 0 ; i < MAXN ; i ++)
        for(int j = 0 ; j < MAXN ; j ++)
        {
            c.mat[i][j] = 0;
            for(int k = 0 ; k < MAXN ; k ++)
            {
                c.mat[i][j] += (a.mat[i][k] * b.mat[k][j]) % mod;
                c.mat[i][j] %= mod;
            }
        }
    return c;
}
Matrix pow_mod_Matrix(Matrix P , ll n , ll mod)
{
    Matrix ans = I, b = P;
    while(n)
    {
        if(n & 1) ans = Mul_Matrix(ans , b , mod);
        n >>= 1;
        b = Mul_Matrix(b , b , mod);
    }
    return ans;
}
void Matrix_init()
{
    for(int i = 0 ; i < MAXN ; i ++) I.mat[i][i] = 1;
}
View Code

gcd+lcm

int gcd(int a,int b){return !b?a:gcd(b,a%b);}
int lcm(int a,int b){return a/gcd(a,b)*b;}

///上面的大数被卡了,可以用下面的
int gcd(int a , int b)
{
    if(a == 0)return 1;
    if(a < 0) return gcd(-a , b);
    while(b)
    {
        ll t = a % b;
        a = b;
        b = t;
    }
    return a;
}
View Code

 

逆元

int inv_exgcd(int x , int mod)
{
    int a , b;
    int re = exgcd(x , mod , a , b);
    if(a < 0) a += (-x / (mod / re) + 1) * (mod / re);
    return a;
}
int inv_pow(int x , int mod)
{
    return pow_mod(x , mod - 2 , mod);
}
View Code

 

exgcd

int exgcd(int a , int b , int &x , int &y){
    if(! b){
        x = 1 , y = 0;
        return a;
    }
    int re = exgcd(b , a % b , y , x);
    y -= (a / b) * x;
    return re;
}
/*
ax + by = c
x *= c / gcd(a , b)
y *= c/ gcd(a , b)
任意解 :
x = x0 + b / gcd(a , b) * t
y = y0 - a / gcd(a , b) * t
t 为任意数
最小整数解x(y):
 ((x * c / gcd(a , b)) % (b / gcd(a , b)) + (b / gcd(a , b))) % (b / gcd(a , b))
*/
View Code

 

中国剩余定理crt(带龟速乘)

int exgcd(int a , int b , int &x , int &y){
    if(! b){
        x = 1 , y = 0;
        return a;
    }
    int re = exgcd(b , a % b , y , x);
    y -= (a / b) * x;
    return re;
}
int Slow_Mul(int x , int y , int mod)///快速乘,避免爆ll
{
    int ans = 0;
    int flag = 1;
    if((x < 0 && y > 0) || (x > 0 && y < 0))flag = -1;
    x = abs(x) , y = abs(y);
    while(y)
    {
        if(y & 1)ans += x % mod , ans %= mod;
        y >>= 1;
        x = (x + x) % mod;
    }
    return ((ans * flag) % mod + mod) % mod;
}
int Li[maxn] , Ti[maxn] , a[maxn] , b[maxn];
int crt(int a[] , int b[] , int n) /// n个数 , a是除数 , b是余数 , 除数互质
{
    int L = 1;
    for(int i = 1 ; i <= n ; i ++) L *= a[i];
    for(int i = 1 ; i <= n ; i ++) Li[i] = L / a[i];
    for(int i = 1 ; i <= n ; i ++){
        int x , y;
        int re = exgcd(Li[i] , a[i] , x , y);
        Ti[i] = x;
    }
    int ans = 0;
    for(int i = 1 ; i <= n ; i ++) ans += Slow_Mul(Slow_Mul(Li[i] ,  Ti[i] , L) , b[i] , L) , ans %= L;
    return (ans + L) % L;
}
View Code

 

扩展中国剩余定理excrt(带龟速乘)

int exgcd(int a , int b , int &x , int &y){
    if(! b){
        x = 1 , y = 0;
        return a;
    }
    int re = exgcd(b , a % b , y , x);
    y -= (a / b) * x;
    return re;
}
int inv_exgcd(int x , int mod)
{
    int a , b;
    int re = exgcd(x , mod , a , b);
    if(a < 0) a += (-x / (mod / re) + 1) * (mod / re);
    return a;
}
int inv_pow(int x , int mod)
{
    return pow_mod(x , mod - 2 , mod);
}
int Slow_Mul(int x , int y , int mod)///快速乘,避免爆ll
{
    int ans = 0;
    int flag = 1;
    if((x < 0 && y > 0) || (x > 0 && y < 0))flag = -1;
    x = abs(x) , y = abs(y);
    while(y)
    {
        if(y & 1)ans += x % mod , ans %= mod;
        y >>= 1;
        x = (x + x) % mod;
    }
    return ((ans * flag) % mod + mod) % mod;
}
int excrt(int a[] , int b[] , int n) /// n个数 , a是除数 , b是余数 , 除数不互质
{
    for(int i = 2 ; i <= n ; i ++) {
        int a1 = a[i - 1] , a2 = a[i] , b1 = b[i - 1] , b2 = b[i];
        int re = gcd(a1 , a2);///11
        if(abs(b2 - b1) % re != 0) return -1;
        a[i] = a1 / re * a2;
        b[i] = Slow_Mul(Slow_Mul(inv_exgcd(a1 / re , a2 / re) , ((b2 - b1) / re) , (a2 / re))  ,  a1 , a[i]) + b1 % a[i];

        b[i] = (b[i] % a[i] + a[i]) % a[i];
    }
    return b[n];
}
View Code

 

Pointard_Rhod定理(大数质因子分解)

#define int long long 
int S = 50;
int Slow_Mod(int a , int b , int mod)
{
    a %= mod , b %= mod;
    int res = 0;
    while(b)
    {
        if(b & 1)res += a , res %= mod;
        a <<= 1 , a %= mod;
        b >>= 1;
    }
    return res;
}
//计算  x^n %c
int pow_mod(int x , int n , int mod)//x^n%c
{
    x %= mod , n %= mod;
    int res = 1;
    while(n)
    {
        if(n & 1) res = Slow_Mod(res , x , mod);
        x = Slow_Mod(x , x , mod);
        n >>= 1;
    }
    return res;
}
//以a为基,n-1=x*2^t      a^(n-1)=1(mod n)  验证n是不是合数
//一定是合数返回true,不一定返回false
bool check(int a , int n , int x , int t)
{
    int res = pow_mod(a , x , n);
    int last = res;
    for(int i = 1 ; i <= t ; i ++)
    {
        res = Slow_Mod(res , res , n);
        if(res == 1 && last != 1 && last != n - 1) return true;//合数
        last = res;
    }
    if(res != 1) return true;
    return false;
}
// Miinter_Rabin()算法素数判定
//是素数返回true.(可能是伪素数,但概率极小)
//合数返回false;
bool Miinter_Rabin(int n)
{
    if(n < 2)return false;
    if(n == 2)return true;
    if((n & 1) == 0) return false;//偶数
    int x = n - 1;
    int t = 0;
    while((x & 1) == 0) x >>= 1 , t ++;
    for(int i = 0 ; i < S ; i ++)
    {
        int a = rand() % (n - 1) + 1;//rand()需要stdlib.h头文件
        if(check(a , n , x , t))
            return false;//合数
    }
    return true;
}
//************************************************
//pointard_rho 算法进行质因数分解,先判是否是素数,特判 1、2 
//************************************************
int Fac[100];//质因数分解结果(刚返回时是无序的)
int tol;//质因数的个数。数组小标从0开始
int gcd(int a , int b)///不要用迭代会TLE 
{
    if(a == 0)return 1;
    if(a < 0) return gcd(-a , b);
    while(b)
    {
        int t = a % b;
        a = b;
        b = t;
    }
    return a;
}
int Pointard_Rho(int x , int c)
{
    int i = 1 , k = 2;
    int x0 = rand() % x;
    int y = x0;
    while(1)
    {
        i ++;
        x0 = (Slow_Mod(x0 , x0 , x) + c) % x;
        int d = gcd(y - x0 , x);
        if(d != 1 && d != x) return d;
        if(y == x0) return x;
        if(i == k)y = x0 , k += k;
    }
}
//对n进行素因子分解 , 特判2,先用米勒罗宾判是不是质数 
void Find_Prime_Fac(int n)
{
    if(Miinter_Rabin(n))//素数
    {
        Fac[tol ++]=n;
        return;
    }
    int p = n;
    while(p >= n)p = Pointard_Rho(p , rand() % (n - 1) + 1);
    Find_Prime_Fac(p);
    Find_Prime_Fac(n / p);
}
View Code

 

欧拉筛

int prime[maxn],minprime[maxn];
int euler(int n)
{int c=0,i,j;for(i=2;i<=n;i++){if(!minprime[i])prime[++c]=i,minprime[i]=i;for(j=1;j<=c&&i*prime[j]<=n;j++)
{minprime[i*prime[j]]=prime[j];if(i%prime[j]==0)break;}}return c;}
View Code

 

积性函数线性筛

void init()
{
    low[1] = f[1] = 1;
    for(int i = 2 ; i <= maxn - 10 ; i ++){
        if(!vis[i]){
            vis[i] = 1 , low[i] = i , f[i] = 2 * i - 1 , prime[++ cnt] = i , k[i] = 1;
        ////low->最小质因子(带指数)即p1^k1 ,  f->积性函数 , k -> 记录次方,即最小质因子的指数是多少 
        } 
        for(int j = 1 ; j <= cnt && prime[j] * i < maxn ; j ++){
            vis[prime[j] * i] = 1;
            if(i % prime[j] == 0){///即 gcd(i , prime[j]) = p1
                low[i * prime[j]] = low[i] * prime[j];///p1^k1再乘上一个p1 
                if(low[i] == i){///是否 是p^k 
                    k[prime[j] * i] = k[i] + 1;
                    ///p^k公式 
                    f[i * prime[j]] = (k[i * prime[j]] + 1) * i * prime[j] - k[i * prime[j]] * i;
                }
                else{/// prime[j]==p1 
                    f[i * prime[j]] = f[i / low[i]] * f[low[i] * prime[j]];///另一个公式 
                }
                break;
            }
            else{
                f[i * prime[j]] = f[i] * f[prime[j]];
                low[i * prime[j]] = prime[j];//prime[j] < p1 
            }
            
        } 
    }
}
View Code

 

posted @ 2020-09-18 15:14  GoodVv  阅读(190)  评论(0编辑  收藏  举报