1.数学

1.数学

1.1矩阵
1.1.1高斯消元

代码:

#include <bits/stdc++.h>
 
using namespace std;
 
#define ll long long
#define ull unsigned long long
#define __ ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
 
 
const int maxn = 1e5 + 10;
const ll mod = 1e9 + 7;
const int inf = 1e9;
const double eps = 1e-10;
 
int n;
double a[110][110];
 
int main() {
    __;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n + 1; ++j) {
            cin >> a[i][j];
        }
    }
    for (int i = 1; i <= n; ++i) {
        int r = i;
        for (int j = i + 1; j <= n; ++j)
            if (fabs(a[j][i]) - fabs(a[r][i]) >= eps)r = j;
        for (int j = 1; j <= n + 1; ++j)
            swap(a[i][j], a[r][j]);
        if (fabs(a[r][r]) <= eps) {
            cout << "No Solution" << endl;
            return 0;
        }
        for (int j = i + 1; j <= n + 1; ++j) {
            a[i][j] /= a[i][i];
        }
        for (int j = 1; j <= n; ++j) {
            if (i != j) {
                for (int k = i + 1; k <= n + 1; ++k) {
                    a[j][k] -= a[j][i] * a[i][k];
                }
            }
        }
    }
    for (int i = 1; i <= n; ++i)cout << fixed << setprecision(2) << a[i][n + 1] << endl;
    return 0;
}
1.1.2矩阵快速幂
struct matrix {
    ll num[5][5];
    int m, mod;//需要赋初值或设为全局变量

    matrix() { memset(num, 0, sizeof num); }

    matrix operator*(const matrix &x) {
        matrix c;
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= m; ++j) {
                for (int k = 1; k <= m; ++k) {
                    c.num[i][j] = (c.num[i][j] + num[i][k] * x.num[k][j] + mod) % mod;
                }
            }
        }
        return c;
    }

    matrix &operator=(const matrix &x) {
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= m; ++j) {
                num[i][j] = x.num[i][j];
            }
        }
        return *this;
    }
};

matrix pow_mod(matrix &x, ll k) {
    matrix ans;
    for (int i = 1; i <= x.m; ++i) {
        ans.num[i][i] = 1;
    }
    while (k) {
        if (k & 1)ans = ans * x;
        x = x * x;
        k >>= 1;
    }
    return ans;
}
1.2整除与剩余
1.2.1欧几里得算法
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }
1.2.2扩展欧几里得算法

求取ax + by = gcd(a, b)

代码:

void e_gcd(int a, int b, int &x, int &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return;
    }
    e_gcd(b, a % b, y, x);
    y -= (a / b) * x;
}
 
/*
    解得ax+by=gcd(a,b)的值,特解:
        x0 = x * c / gcd(a, b);
        y0 = y * c / gcd(a, b);
    所有解即为:
        x = x0 + k * b / gcd(a, b);
        y = y0 - k * a / gcd(a, b);
*/
1.2.3线性乘法逆元
/*1 - n的乘法逆元,m为模数*/
    ni[1] = 1;
    for (int i = 2; i <= n; ++i) {
        ni[i] = (m - m / i) * ni[m % i] % m;
    }
1.3素数*
1.3.1素数筛法

线性筛素数O(n):

bool vis[maxn];
int ans[maxn], tot;
 
void get_prime(int n) {
    memset(vis, 1, sizeof(vis));
    vis[0] = vis[1] = 0;
    for (int i = 2; i <= n; ++i) {
        if (vis[i]) {
            ++tot;
            ans[tot] = i;
        }
        for (int j = 1; ((j <= tot) && (i * ans[j] <= n)); ++j) {
            vis[i * ans[j]] = 0;
            if (i % ans[j] == 0)break;
        }
    }
}
1.3.2素数判定

素数测试(Miller-Rabin算法):

ll mult_mod(ll a, ll b, ll c) {
    a %= c;
    b %= c;
    ll ret = 0;
    ll tmp = a;
    while (b) {
        if (b & 1) {
            ret += tmp;
            if (ret > c) ret -= c;
        }
        tmp <<= 1;
        if (tmp > c) tmp -= c;
        b >>= 1;
    }
    return ret;
}

ll pow_mod(ll a, ll b, ll m) {
    ll ans = 1;
    while (b) {
        if (b & 1)ans = ans * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return ans;
}

bool check(ll a, ll n, ll x, ll t) {
    ll ret = pow_mod(a, x, n);
    ll last = ret;
    for (int i = 1; i <= t; i++) {
        ret = mult_mod(ret, ret, n);
        if (ret == 1 && last != 1 && last != n - 1) return true;
        last = ret;
    }
    if (ret != 1) return true;
    else return false;
}

const int S = 20;//测试次数

bool is_prime(ll n) {
    if (n < 2) return false;
    if (n == 2) return true;
    if ((n & 1) == 0) return false;
    ll x = n - 1;
    ll t = 0;
    while ((x & 1) == 0) {
        x >>= 1;
        t++;
    }
    srand(time(NULL));
    for (int i = 0; i < S; i++) {
        ll a = rand() % (n - 1) + 1;
        if (check(a, n, x, t)) return false;
    }
    return true;
}
1.3.3质因数分解
/*
	质因数分解:
		n表示待分解的整数
		&tot表示不同质因数的个数
		p[i]表示第i个质因数的值
		q[i]表示第i个质因数的指数
    调用方式 factor(n,p,q,tot);
*/
void factor(ll n, ll *p, ll *q, int &tot) {
    ll temp, now;
    temp = (int) sqrt(n);
    tot = 0;
    now = n;
    for (int i = 2; i <= temp; ++i) {
        if (now % i == 0) {
            p[++tot] = i;
            q[tot] = 0;
            while (now % i == 0) {
                ++q[tot];
                now /= i;
            }
        }
    }
    if (now != 1) {
        p[++tot] = now;
        q[tot] = 1;
    }
}
1.4欧拉函数
1.4.1计算欧拉函数
int euler_phi(int n) {
    int m = (int) sqrt(n + 0.5);
    int ans = n;
    for (int i = 2; i <= m; ++i)
        if (n % i == 0) {
            ans = ans / i * (i - 1);
            while (n % i == 0)n /= i;
        }
    if (n > 1)ans = ans / n * (n - 1);
    return ans;
}
1.4.2筛法构造欧拉函数表
int phi[maxn];
 
void phi_table(int n) {
    phi[1] = 1;
    for (int i = 2; i <= n; i++) {
        if (!phi[i]) {
            for (int j = i; j <= n; j += i) {
                if (!phi[j])phi[j] = j;
                phi[j] = (phi[j] / i) * (i - 1);
            }
        }
    }
}
1.5其他
1.5.1快速幂
#define ll long long
ll pow_mod(ll a, ll b, ll m) {
    ll ans = 1;
    while (b) {
        if (b & 1)ans = ans * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return ans;
}
1.5.2 卢卡斯定理

卢卡斯定理求C(n,m)%p的值
注意:p一定为一个不大的素数
先调用init(p);计算所有阶乘的值
然后lucas(n,m,p)即为所求

const int maxn = 1e6 + 10;
ll f[maxn];

void init(ll p) {
    f[0] = 1;
    for (int i = 1; i <= p; ++i)
        f[i] = f[i - 1] * i % p;
}

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

ll lucas(ll n, ll m, ll p) {
    ll ans = 1;
    while (n && m) {
        ll a = n % p, b = m % p;
        if (a < b)return 0;
        ans = ans * f[a] % p * pow_mod(f[b] * f[a - b] % p, p - 2, p) % p;
        n /= p;
        m /= p;
    }
    return ans;
}
1.5.3 高精度整数(Java)
import java.io.*;
import java.util.*;
import java.math.*;
 
public class Main {
    public static void main(String args[]) {
        Scanner cin = new Scanner(System.in);
        BigInteger a, b;
        //以文件EOF结束
        while (cin.hasNext()) {
            a = cin.nextBigInteger();
            b = cin.nextBigInteger();
 
            System.out.println(a.add(b)); //大整数加法
            System.out.println(a.subtract(b)); //大整数减法
            System.out.println(a.multiply(b)); //大整数乘法
            System.out.println(a.divide(b)); //大整数除法(取整)
            System.out.println(a.remainder(b)); //大整数取模
 
            //大整数的比较
            if (a.compareTo(b) == 0) System.out.println("a == b"); //大整数a==b
            else if (a.compareTo(b) > 0) System.out.println("a > b"); //大整数a>b
            else if (a.compareTo(b) < 0) System.out.println("a < b"); //大整数a<b
 
            //大整数绝对值
            System.out.println(a.abs()); //大整数a的绝对值
 
            //大整数的幂
            int exponent = 10;
            System.out.println(a.pow(exponent)); //大整数a的exponent次幂
 
            //返回大整数十进制的字符串表示
            System.out.println(a.toString());
 
            //返回大整数p进制的字符串表示
            int p = 8;
            System.out.println(a.toString(p));
        }
    }
}
1.5.4 斐波那契数列求循环节
//先调用getprime()

#define ll unsigned long long

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

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}

struct Matrix {
    ll mat[2][2];

    Matrix() { memset(mat, 0, sizeof mat); }
};

Matrix mul_M(Matrix a, Matrix b, ll mod) {
    Matrix ans;
    for (int i = 0; i < 2; ++i) {
        for (int j = 0; j < 2; ++j) {
            ans.mat[i][j] = 0;
            for (int k = 0; k < 2; ++k) {
                ans.mat[i][j] += a.mat[i][k] * b.mat[k][j] % mod;
                if (ans.mat[i][j] >= mod)ans.mat[i][j] -= mod;
            }
        }
    }
    return ans;
}

Matrix pow_M(Matrix a, ll n, ll mod) {
    Matrix ans;
    for (int i = 0; i < 2; ++i) ans.mat[i][i] = 1;
    Matrix tmp = a;
    while (n) {
        if (n & 1)ans = mul_M(ans, tmp, mod);
        tmp = mul_M(tmp, tmp, mod);
        n >>= 1;
    }
    return ans;
}

ll pow_m(ll a, ll n, ll mod) {
    ll ans = 1, tmp = a % mod;
    while (n) {
        if (n & 1)ans = ans * tmp % mod;
        tmp = tmp * tmp % mod;
        n >>= 1;
    }
    return ans;
}

const int maxn = 1e6 + 10;

int prime[maxn];

void getprime() {
    memset(prime, 0, sizeof prime);
    for (int i = 2; i <= maxn; ++i) {
        if (!prime[i])prime[++prime[0]] = i;
        for (int j = 1; j <= prime[0] && prime[j] * i <= maxn; ++j) {
            prime[prime[j] * i] = 1;
            if (i % prime[j] == 0)break;
        }
    }
}

ll factor[100][2];
int fatcnt;

int getfactors(ll x) {
    fatcnt = 0;
    ll tmp = x;
    for (int i = 1; prime[i] * prime[i] <= tmp; ++i) {
        factor[fatcnt][1] = 0;
        if (tmp % prime[i] == 0) {
            factor[fatcnt][0] = prime[i];
            while (tmp % prime[i] == 0) {
                factor[fatcnt][1]++;
                tmp /= prime[i];
            }
            fatcnt++;
        }
    }
    if (tmp != 1) {
        factor[fatcnt][0] = tmp;
        factor[fatcnt++][1] = 1;
    }
    return fatcnt;
}

int legendre(ll a, ll p) {
    if (pow_m(a, (p - 1) >> 1, p) == 1)return 1;
    else return -1;
}

int f0 = 1;
int f1 = 1;

ll getfib(ll n, ll mod) {
    if (mod == 1)return 0;
    Matrix A;
    A.mat[0][0] = 0;
    A.mat[1][0] = 1;
    A.mat[0][1] = 1;
    A.mat[1][1] = 1;
    Matrix B = pow_M(A, n, mod);
    ll ans = f0 * B.mat[0][0] + f1 * B.mat[1][0];
    return ans % mod;
}

ll fac[maxn];

ll G(ll p) {
    ll num;
    if (legendre(5, p) == 1)num = p - 1;
    else num = 2 * (p + 1);
    int cnt = 0;
    for (ll i = 1; i * i <= num; ++i) {
        if (num % i == 0) {
            fac[cnt++] = i;
            if (i * i != num) {
                fac[cnt++] = num / i;
            }
        }
    }
    sort(fac, fac + cnt);
    ll ans;
    for (int i = 0; i < cnt; ++i) {
        if (getfib(fac[i], p) == f0 && getfib(fac[i] + 1, p) == f1) {
            ans = fac[i];
            break;
        }
    }
    return ans;
}

ll find_loop(ll n) {
    getfactors(n);
    ll ans = 1;
    for (int i = 0; i < fatcnt; ++i) {
        ll record = 1;
        if (factor[i][0] == 2)record = 3;
        else if (factor[i][0] == 3)record = 8;
        else if (factor[i][0] == 5)record = 20;
        else record = G(factor[i][0]);
        for (int j = 1; j < factor[i][1]; ++j) {
            record *= factor[i][0];
        }
        ans = lcm(ans, record);
    }
    return ans;
}

1.5.5 FFT

stl complex实现:

const int maxn = 5e5 + 10;
const ld PI = acos(-1.0);

#define cp complex<double>
int rev[maxn], ans[maxn];
cp A[maxn], B[maxn];

void FFT(cp *a, int n, int inv) {
    int bit = 0;
    while ((1 << bit) < n)++bit;
    for (int i = 0; i <= n - 1; ++i) {
        rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
        if (i < rev[i])swap(a[i], a[rev[i]]);
    }
    for (int len = 2; len <= n; len <<= 1) {
        int mid = len >> 1;
        cp unit(cos(PI / mid), inv * sin(PI / mid));
        for (int i = 0; i < n; i += len) {
            cp omega(1, 0);
            for (int j = 0; j < mid; ++j, omega *= unit) {
                cp x = a[i + j], y = omega * a[i + j + mid];
                a[i + j] = x + y;
                a[i + j + mid] = x - y;
            }
        }
    }
    if (inv == -1) {
        for (int i = 0; i <= n; ++i)a[i] /= n;
    }
}

// use FFT
// Array A[0...n-1]
// Array B[0...m-1]
void mul() {
    int bitn = 1;
    while (bitn < n + m)bitn <<= 1;
    FFT(A, bitn, 1);
    FFT(B, bitn, 1);
    for (int i = 0; i < bitn; ++i) {
        A[i] = A[i] * B[i];
    }
    FFT(A, bitn, -1);
    for (int i = 0; i < n + m - 1; ++i) {
        ans[i] += (int) (A[i].real() + 0.5);
    }
}

手写complex:

const int maxn = 2e6 + 10;
const double PI = acos(-1.0);

struct Complex {
    double x, y;

    Complex(double _x = 0.0, double _y = 0.0) {
        x = _x;
        y = _y;
    }

    Complex operator-(const Complex &b) const {
        return Complex(x - b.x, y - b.y);
    }

    Complex operator+(const Complex &b) const {
        return Complex(x + b.x, y + b.y);
    }

    Complex operator*(const Complex &b) const {
        return Complex(x * b.x - y * b.y, x * b.y + y * b.x);
    }
};

int rev[maxn];

#define cp Complex

void FFT(cp *a, int n, int inv) {
    int bit = 0;
    while ((1 << bit) < n)++bit;
    for (int i = 0; i <= n - 1; ++i) {
        rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (bit - 1));
        if (i < rev[i])swap(a[i], a[rev[i]]);
    }
    for (int len = 2; len <= n; len <<= 1) {
        int mid = len >> 1;
        cp unit(cos(PI / mid), inv * sin(PI / mid));
        for (int i = 0; i < n; i += len) {
            cp omega(1, 0);
            for (int j = 0; j < mid; ++j, omega = omega * unit) {
                cp x = a[i + j], y = omega * a[i + j + mid];
                a[i + j] = x + y;
                a[i + j + mid] = x - y;
            }
        }
    }
    if (inv == -1) {
        for (int i = 0; i <= n; ++i)a[i].x /= n;
    }
}


1.5.6 FWT
const int maxn = 5e5 + 10;
const int mod = 998244353;
const int OR = 1, AND = 2, XOR = 3, XNOR = 4;

int add(int x, int y) {
    return (x += y) >= mod ? x - mod : x;
}

int sub(int x, int y) {
    return (x -= y) < 0 ? x + mod : x;
}

void fwt(int op, int *a, int n, int rev) {
    for (int d = 1; d < n; d <<= 1) {
        for (int m = d << 1, i = 0; i < n; i += m) {
            for (int j = 0; j < d; ++j) {
                int x = a[i + j], y = a[i + j + d];
                if (rev == 1) {
                    if (op == OR)a[i + j + d] = add(y, x);
                    if (op == AND)a[i + j] = add(x, y);
                    if (op == XOR)a[i + j] = add(x, y), a[i + j + d] = sub(x, y);
                    if (op == XNOR)a[i + j] = sub(y, x), a[i + j + d] = add(x, y);
                } else {
                    ll inv2 = (mod + 1) >> 1;
                    if (op == OR)a[i + j + d] = sub(y, x);
                    if (op == AND)a[i + j] = sub(x, y);
                    if (op == XOR)a[i + j] = 1ll * add(x, y) * inv2 % mod, a[i + j + d] = 1ll * sub(x, y) * inv2 % mod;
                    if (op == XNOR)a[i + j] = 1ll * sub(y, x) * inv2 % mod, a[i + j + d] = 1ll * add(x, y) * inv2 % mod;
                }
            }
        }
    }
}

int A[maxn], B[maxn];

void mul(int op, int *a, int n, int *b, int m, int *ans) {
    int bitn = 1;
    while (bitn < (n + m))bitn <<= 1;
    for (int i = 0; i < bitn; ++i)A[i] = a[i], B[i] = b[i];
    fwt(op, A, bitn, 1);
    fwt(op, B, bitn, 1);
    for (int i = 0; i < bitn; ++i)ans[i] = 1ll * A[i] * B[i] % mod;
    fwt(op, ans, bitn, -1);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值