ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

一些杂项算法

2022-08-10 20:33:01  阅读:161  来源: 互联网

标签:le10 le int 复杂度 long 算法 ans 一些 杂项


KMP

代码实现

时间复杂度\(O(n + m)\)

int n, m;
int next[M + 1], f[N + 1];
char s[N + 2], p[M + 2];

void kmp() {
    n = strlen(s + 1), m = strlen(p + 1);
    int j = 0;
    nxt[1] = 0;
    for (int i = 2; i <= m; i++) {
        while (j > 0 && p[j + 1] != p[i])
            j = nxt[i];
        if (p[i + 1] == p[i])
            j++;
        nxt[i] = j;
    }
    j = 0;
    for (int i = 1; i <= n; i++) {
        while ((j == m) || (j > 0 && p[j + 1] != s[i]))
            j = nxt[j];
        if (p[j + 1] == s[i])
            j++;
        f[i] = j;
    }
}
/*
简化写法 两个字符串拼接起来用#分割
    int n = strlen(s+1), m = strlen(p+1);
    p[m + 1] = '#';
    for (int i = 1, j = m + 2; i <= n; i++, j++)
        p[j] = s[i];
    int j = 0;
    nxt[1] = 0;
    for (int i = 2; i <= n + m + 1; i++) {
        while (j && p[i] != p[j + 1])
            j = nxt[j];
        if (p[i] == p[j + 1])
            j++;
        nxt[i] = j;
    }
*/

exkmp

代码实现

时间复杂度\(O(n)\)

void exkmp() {
	int L = 1, R = 0;
    z[1] = 0;
	for (int i = 2; i <= n; i++) {
        if (l > R) z[i] = 0;
        else {
            int k = i - L + 1;
            z[i] = min(z[k], R - i + 1);
        }
        while (i + z[i] <= n && s[z[i] + 1] == s[i + z[i]])
            z++;
        if (i + z[i] - 1 > R)
            L = i, R = i + z[i] - 1;
    }
}

快速幂

代码实现

时间复杂度\(O(logn)\)

long long qp(long long a, int n) {
    long long ans = 1;
    for (; n; n >>= 1) {
        if (n & 1) ans *= a, ans %= p;
        a *= a, a %= p;
    }
}

快速乘

代码实现

用于快速计算 \(a \times b \pmod p\)

当 \(0 \le a,b\le10^9,1\le P\le10^9\)时,可以直接计算

当 \(0 \le a,b\le10^{18},1\le P\le10^9\)时,可以\((a\%p \times b\%p)\%p\)进行计算

当 \(0 \le a,b\le10^{18},1\le P\le10^{18}\)时,需要用到快速乘

时间复杂度\(O(logn)\)

long long qm(long long a, long long b, long long p) {
    long long ans = 0;
    a %= p;//重要
    for (; b; b >>= 1) {
        if (b & 1) ans += a, ans %= p;
        a += a;
        a %= p;
    }
    return ans;
}

矩阵乘法

代码实现

设A是一个n行m列的矩阵,B是一个m行k列的矩阵,矩阵\(C=A\times B\)

计算方式:\(C_{i,j}=\sum_{k=1}^mA_{i,j}B_{k,j}\)

A的列数等于B的行数才可以进行矩阵乘法

const int K = 200, P = 1e9 + 7;
int n;
long long a[N + 1][N + 1], f[N + 1];
void aa() {
    long long w[N + 1][N + 1];
    memset(w, 0, sizeof(w));
    for (int i = 1; i <= n; i++) 
        for (int j = 1; j <= n; j++)
            for (int k = 1; k <= n; k++)
                w[i][j] += a[i][k] * a[k][j], w[i][j] %= p;
    memcpy(a, w, sizeof(a));
}

void fa() {
    long long w[N + 1];
    memset(w, 0, sizeof(w));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            w[i] += f[i] * a[j][i], w[i] %= p;
    memcpy(f, w, sizeof(f));
}

void matrixpow(int k) {
    for (; k; k /= 2) {
        if (k & 1) fa();
        aa();
    }
}

标签:le10,le,int,复杂度,long,算法,ans,一些,杂项
来源: https://www.cnblogs.com/guyuLihua/p/16573771.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有