• GDOI2021游记


    I.考前抱佛jio记

    Talk is cheap show me the code.

    I.I 字符串系列

    I.I.I Hash

    想必是不用说了。

    I.I.II 前缀函数与 Knuth-Morris-Pratt 算法

    I.I.II.I 计算前缀函数

    算法1:枚举

    复杂度(Theta(n^3))

    vector<int> prefix_function(char *s){
        int n = strlen(s+1);
        vector<int> pi(n);
        for(int i=1; i<=n; i++){
            for(int j=i; j>=0; j--){
                bool flag = 1;
                for(int k=1; k<=j; k++){
                    if(str[k] != str[i-k+1]){
                        flag = 0;
                        break;
                    }
                }
                if(flag){
                    pi[i] = j;
                    break;
                }
            }
        }
        return pi;
    }
    
    优化1:相邻前缀函数至多增加1

    复杂度(Theta(n^2))

    vector<int> prefix_function(char *s){
        int n = str(s+1);
        vector<int> pi(n);
        for(int i=1; i<=n; i++){
            for(int j=pi[i-1]+1; j>=0; j--){
                bool flag = 1;
                for(int k=1; k<=j; k++){
                    if(str[k] != str[i-k+1]){
                        flag = 0;
                        break;
                    }
                }
                if(flag){
                    pi[i] = j;
                    break;
                }
            }
        }
        return pi;
    }
    
    优化2:失配指针

    复杂度(Theta(n))

    vector<int> prefix_function(char *s){
        int n = str(s+1);
        vector<int> pi(n);
        for(int i=1; i<=n; i++){
            int j = pi[i-1];
            while(j and s[i] != s[j+1]) j = pi[j-1];
            if(s[i] == s[j+1]) j ++;
            pi[i] = j;
        }
        return pi;
    }
    

    I.I.II.II Knuth-Morris-Pratt algorithm

    复杂度(Theta(n+m))

    vector<int> Knuth_Morris_Pratt_algorithm(char *s, char *p){
        int n = str(s+1), m = str(p+1);
        vector<int> pos, nxt;
        nxt = prefix_function(char *p);
        for(int i=1, j=0; i<=n; i++){
            while(j and s[i] != p[j+1]) j = nxt[j];
            if(p[j+1] == s[i]) j ++;
            if(j == m) pos.push_back(i-j+1);
        }
        return pos;
    }
    

    (字符串系列未完待续,咕咕咕~)

    I.II 数学系列

    I.II.I 从快速幂开始

    int qpow(int x, int y){
        int cnt = 1, basic = x;
        while(y){
            if(y&1) cnt = cnt*basic;
            basic = basic*basic, y >>= 1;
        }
        return cnt;
    }
    
    矩阵类
    struct Matrix
    {
        int a[maxn][maxn], n;
        void clear(int x)
        {
            n = x;
            for (int i = 1; i <= n; i++)
                a[i][i] = 1;
        }
        void init(int x)
        {
            n = x;
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= n; j++)
                    a[i][j] = 0;
        }
        Matrix operator*(const Matrix &x) const
        {
            Matrix c;
            c.init(n);
            for (int k = 1; k <= n; k++)
                for (int i = 1; i <= n; i++)
                    for (int j = 1; j <= n; j++)
                        (c.a[i][j] += a[i][k] * x.a[k][j] % mod) %= mod;
            return c;
        }
        void debug()
        {
            for (int i = 1; i <= n; i++)
            {
                for (int j = 1; j <= n; j++)
                    cout << a[i][j] << " ";
                cout << endl;
            }
        }
    };
    

    I.II.II 从gcd开始

    int gcd(int x, int y){
        if(y == 0) return x;
        return gcd(y, x%y);
    }
    

    I.II.III 扩展欧几里得EX-gcd

    定理:裴蜀定理

    [ax+by=gcd(a,b) ]

    简单推导:

    [ax+by=(a,b)=(b,a\%b)=bx'+(a\%b)y'=bx'+(a-bcdotleftlfloor dfrac{a}{b} ight floor)y'\ herefore egin{cases}x=y'\y=x'-leftlfloorfrac{a}{b} ight floor y'end{cases} ]

  • 相关阅读:
    C语言 数组排序 – 冒泡法排序
    类加载过程
    布隆过滤器的原理及应用
    回答两个被频繁问到的代码写法问题
    关于分布式事务的理解
    根据使用者反馈,对开源项目 go-gin-api 新增两个功能
    图书速度 | 《如何高效学习》
    报错kernel:NMI watchdog: BUG: soft lockup
    容器Jenkins中运行docker
    容器Jenkins中运行docker
  • 原文地址:https://www.cnblogs.com/GDOI2018/p/14638944.html
Copyright © 2020-2023  润新知