• buerdepepeqi 的模版


    buerdepepeqi的模板

    头文件

    #include <set>
    #include <map>
    #include <deque>
    #include <queue>
    #include <stack>
    #include <cmath>
    #include <ctime>
    #include <bitset>
    #include <cstdio>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    typedef long long LL;
    typedef pair<LL, LL> pLL;   
    typedef pair<LL, int> pLi;
    typedef pair<int, LL> pil;;
    typedef pair<int, int> pii;
    typedef unsigned long long uLL;
    #define ls rt<<1
    #define rs rt<<1|1
    #define lson l,mid,rt<<1
    #define rson mid+1,r,rt<<1|1
    #define bug printf("*********
    ")
    #define FIN freopen("input.txt","r",stdin);
    #define FON freopen("output.txt","w+",stdout);
    #define IO ios::sync_with_stdio(false),cin.tie(0)
    #define debug1(x) cout<<"["<<#x<<" "<<(x)<<"]
    "
    #define debug2(x,y) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<"]
    "
    #define debug3(x,y,z) cout<<"["<<#x<<" "<<(x)<<" "<<#y<<" "<<(y)<<" "<<#z<<" "<<z<<"]
    "
    LL read() {
        int x = 0, f = 1; char ch = getchar();
        while(ch < '0' || ch > '9') {
            if(ch == '-')f = -1;
            ch = getchar();
        }
        while(ch >= '0' && ch <= '9') {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    const double eps = 1e-8;
    const int mod = 1e9+7;
    const int maxn = 3e5 + 5;
    const int INF = 0x3f3f3f3f;
    const LL INFLL = 0x3f3f3f3f3f3f3f3f;
    
    

    数学

    费马小定理

    a是不能被质数p整除的正整数,则有a^(p-1)≡ 1 mod p,即a^(p-1) mod p=1;
    推论:对于不能被质数p整除的正整数a,有a^p≡ a mod p
    a^b%p=a^(b%(p-1))%p
    

    逆元

    /*O(n)打表求1~n的逆元*/
    LL inv[maxn];
    void init() {
        inv[1] = 1;
        for (int i = 2; i < maxn; i++) inv[i] = inv[mod % i] * (mod - mod / i) % mod;
    }
    
    

    矩阵快速幂

    struct matrix {//矩阵
        int n;//长
        int m;//宽
        long long a[105][105];
        matrix() {//构造函数
            n = 2;
            m = 2;
            memset(a, 0, sizeof(a));
        }
        matrix(int x, int y) {
            n = x;
            m = y;
            memset(a, 0, sizeof(a));
        }
        void print() {
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= m; j++) {
                    printf("%d ", a[i][j]);
                }
                printf("
    ");
            }
        }
        void setv(int x) {//初始化
            if(x == 0) {
                memset(a, 0, sizeof(a));
            }
            if(x == 1) {
                memset(a, 0, sizeof(a));
                for(int i = 1; i <= n; i++) a[i][i] = 1;
            }
        }
        friend matrix operator *(matrix x, matrix y) { //矩阵乘法
            matrix tmp = matrix(x.n, y.m);
            for(int i = 1; i <= x.n; i++) {
                for(int j = 1; j <= y.m; j++) {
                    tmp.a[i][j] = 0;
                    for(int k = 1; k <= y.n; k++) {
                        tmp.a[i][j] += (x.a[i][k] * y.a[k][j]) % mod;
                    }
                    tmp.a[i][j] %= mod;
                }
            }
            return tmp;
        }
    };
    matrix fast_pow(matrix x, long long k) { //矩阵快速幂
        matrix ans = matrix(n, n);
        ans.setv(1);//初始化为1
        while(k > 0) { //类似整数快速幂
            if(k & 1) {
                ans = ans * x;
            }
            k >>= 1;
            x = x * x;
        }
        return ans;
    }
    

    欧拉定理和欧拉函数

    欧拉函数phi(m):当m>1是,phi(m)表示比m小且与m互质的正整数个数
    欧拉定理:a^phi(n) = 1 mod n
    a^x = a^(x % phi(p) + p) (mod p)
    //打表
    int b[N],prime[N],phi[N];
    void init(){  //求欧拉函数和素数
        int i,j,k,c=0;
        memset(b,0,sizeof(b));
        for(i=2;i<N;i++){
            if(b[i]==0){
                prime[++c]=i;
                phi[i]=i-1;
            }
            for(j=1;(j<=c)&&(k=i*prime[j])<N;j++){
                b[k]=1;
                if(i%prime[j])  phi[prime[j]*i]=phi[i]*(prime[j]-1);
                else phi[prime[j]*i]=phi[i]*prime[j];
            }
        }
    }
    //直接计算欧拉函数
    int phi (int n) {
        int res = n;
        for (int i = 2; i * i <= n; ++i) {
            if (n % i == 0) {
                res -= res / i;
                while (n % i == 0) n /= i;
            }
        }
        return n > 1 ? res / n * (n - 1) : res;
    }
    //欧拉函数递归调用
    //计算dp[i] = 2^dp[i+1] % mod,需要先计算mod的phi,以及phi(mod)的phi直到为1
    //dp[i] = 2^(dp[i+1]%phi(mod)+phi(mod)) %mod
    const int MX = 1e5 + 5;
    const ll mod = 1e9 + 7;
    ll m[50], dp[MX][50];
    int sz, n;
    int Phi (int n) {
        int res = n;
        for (int i = 2; i * i <= n; ++i) {
            if (n % i == 0) {
                res -= res / i;
                while (n % i == 0) n /= i;
            }
        }
        return n > 1 ? res / n * (n - 1) : res;
    }
    void init() {
        int x = mod;
        sz = 0;
        m[++sz] = x;
        while (x != 1) m[++sz] = Phi (x), x = m[sz], cout << x << endl;
    }
    ll pow (ll a, ll b, ll m) {
        ll ret = 1;
        while (b) {
            if (b & 1) ret = ret * a % m;
            a = a * a % m;
            b >>= 1;
        }
        return ret;
    }
    int main() {
        init();
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j < sz; j++) {
                dp[i][j] = pow (2ll, dp[i - 1][j + 1], m[j]) * 3 - 3;
                while (dp[i][j] < 0) dp[i][j] += m[j];
                while (dp[i][j] >= m[j]) dp[i][j] -= m[j];
            }
        }
        printf ("%lld
    ", dp[n][1] % m[1]);
    }
     
    

    扩展欧几里得定理

    //递归
    LL ex_gcd(LL a, LL b, LL &x, LL &y) {
        if(b == 0) {
            x = 1, y = 0;
            return a;
        }
        int d = ex_gcd(b, a % b, x, y);
        int z = x;
        x = y;
        y = z - y * (a / b);
        return d;
    }
    //非递归
    //返回值为 gcd 以及 a,b 的系数
    pair<ll, PLL> exgcd(ll a,ll b){
        valarray<ll>equation[2] = {{a,1,0},{b,0,1}};
        while (equation[1][0]) {
            ll q = equation[0][0]/equation[1][0];
            equation[0] -= q * equation[1];
            swap(equation[0], equation[1]);
        }
        return MP(equation[0][0],MP(equation[0][1],equation[0][2]));
    }
    
    

    组合数

    1、普通组合数

    void gcd(LL a, LL b, LL &d, LL &x, LL &y) {
        if(!b) {
            d = a;
            x = 1;
            y = 0;
        } else {
            gcd(b, a % b, d, y, x);
            y -= x * (a / b);
        }
    }
    LL inv(LL a, LL n) {
        LL d, x, y;
        gcd(a, n, d, x, y);
        return (x % n + n) % n;
    }
    LL fac[maxn], fav[maxn];
    LL C(LL n, LL m) {
        return fac[n] * fav[m] % mod * fav[n - m] % mod;
    }
    void init() {
        fac[0] = 1; fav[0] = 1;
        for(int i = 1; i < maxn; i++)fac[i] = fac[i - 1] * i % mod;
        for(int i = 1; i < maxn; i++)fav[i] = inv(fac[i], mod);
    }
    

    2、Lucas组合数

    LL p;
    LL n, m;
    LL fac[maxn];
    LL pow(LL y, int z, int p) {
        y %= p; LL ans = 1;
        for(int i = z; i; i >>= 1, y = y * y % p)if(i & 1)ans = ans * y % p;
        return ans;
    }
    LL C(LL n, LL m) {
        if(m > n)return 0;
        return ((fac[n] * pow(fac[m], p - 2, p)) % p * pow(fac[n - m], p - 2, p) % p);
    }
    LL Lucas(LL n, LL m) {
        if(!m)return 1;
        return C(n % p, m % p) * Lucas(n / p, m / p) % p;
    }
    int main() {
        scanf("%lld%lld%lld", &n, &m, &p);
        fac[0] = 1;
        for(int i = 1; i <= p; i++) {
            fac[i] = fac[i - 1] * i % p;
        }
        printf("%lld
    ", Lucas(n, m) );
        return 0;
    }
    

    3、卡特兰数

    卡特兰数是一种经典的组合数,经常出现在各种计算中,其前几项为 :
    1, 2, 5, 14, 42,
    132, 429, 1430, 4862, 16796,
    58786, 208012, 742900, 2674440, 9694845,
    35357670, 129644790, 477638700, 1767263190,
    6564120420, 24466267020, 91482563640, 343059613650, 1289904147324,
    4861946401452, ...

    [C_n=frac{(2n)!}{(n+1)!n!} ]

    卡特兰数满足如下递归

    [C_0=0quad and quad C_{n+1}=frac{2(2n+1)}{n+2}C_n\ C_0=1quad and quad C_{n+1}=sum_{i=0}^{n}C_iC_{n-i}quad n>=0 ]

    卡特兰数的渐进增长为

    [C_n=> frac{4^n}{n^{3/2}sqrt{pi}} ]

    所有的奇卡塔兰数Cn都满足n = 2^k − 1。
    所有其他的卡塔兰数都是偶数。

    卡特兰数的经典问题
    1. n个左括号与n个右括号组成的合法序列的数量为卡特兰数
    2. 1,2,···,n经过一个栈,形成的合法的出栈序列的数量为卡特兰数
    3. n个节点构成不同的二叉树的数量为卡特兰数
    4. 在平面直角坐标系上,每一步只能向上走或向右走,从(0,0)走到(n,n)并且除了两个端点外不能接触直线y=x的路线数量为2*Cat_n-1
    5. Cn表示通过连结顶点而将n + 2边的凸多边形分成三角形的方法个数
    6. Cn表示集合{1, …, n}的不交叉划分的个数. 其中每个段落的长度为2
    7. Cn表示用n个长方形填充一个高度为n的阶梯状图形的方法个数
      下图为 n = 4的情况:

    4、错排公式

    [D(n)=(n-1)*[D(n-1) +D(n-2)] ]

    约瑟夫环

    //最后一个报号的人
    int main(){
        int n, m, i, s = 0;
        scanf("%d%d", &n, &m);
        for (i = 2; i <= n; i++)
            s = (s + m) % i;
        printf ("
    The winner is %d
    ", s+1);
    }
    //第k个出去的人
    #include<bits/stdc++.h>
     
    using namespace std;
     
    int main(){
        int n,k;
        while(scanf("%d%d",&n,&k)==2){//n个人第k个人走,最后一个人是谁
            int t; scanf("%d",&t);
            while(t--){
                int q; scanf("%d",&q);
                long long N = (long long)q*k;
                while(N>n){
                    N = (N-n-1)/(k-1)+N-n;
                }
                printf("%d%c",(int)N," 
    "[!t]);
            }
        }
        return 0;
    }
    

    莫比乌斯函数

    //线性筛求莫比乌斯函数
    int mu[maxn];
    int prime[maxn];
    int not_prime[maxn];
    int n,tot;
    void Mobiwus(){
        mu[1] = 1;
        for(int i = 2; i <= n; i++) {
            if(!not_prime[i]) {
                prime[++tot] = i;
                mu[i] = -1;
            }
            for(int j = 1; prime[j]*i <= n; j++) {
                not_prime[prime[j]*i] = 1;
                if(i % prime[j] == 0) {
                    mu[prime[j]*i] = 0;
                    break;
                }
                mu[prime[j]*i] = -mu[i];
            }
        }
    }
    

    BM递推式

    namespace linear_seq {
    #define pb push_back
    #define SZ(x) ((int)(x).size())
    #define rep(i,a,b) for(int i=(a);i<(b);++i)
    #define per(i,a,b) for(int i=(a)-1;i>=(b);--i)
        typedef vector<int> VI;
        const int N = 10010;
        const LL mod = 1e9 + 7;
        LL res[N], base[N], cnt[N], val[N];
        LL power(LL a, LL b) {
            LL ret = 1; a %= mod;
            while(b) {
                if(b & 1)ret = ret * a % mod;
                a = a * a % mod;
                b >>= 1;
            }
            return ret;
        }
        vector<int> v;
        void mul(LL *a, LL *b, int k) {
            rep(i, 0, k + k) cnt[i] = 0;
            rep(i, 0, k) if (a[i]) rep(j, 0, k) cnt[i + j] = (cnt[i + j] + a[i] * b[j]) % mod;
            per(i, k + k, k) if (cnt[i]) rep(j, 0, SZ(v))
                cnt[i - k + v[j]] = (cnt[i - k + v[j]] - cnt[i] * val[v[j]]) % mod;
            rep(i, 0, k) a[i] = cnt[i];
        }
        int solve(LL n, VI a, VI b) { // a系数 b初值 b[n+1]=a[0]*b[n]+...
            LL ans = 0, pnt = 0;
            int k = SZ(a);
            rep(i, 0, k) val[k - 1 - i] = -a[i]; val[k] = 1;
            v.clear();
            rep(i, 0, k) if (val[i] != 0) v.push_back(i);
            rep(i, 0, k) res[i] = base[i] = 0;
            res[0] = 1;
            while ((1LL << pnt) <= n) pnt++;
            per(p, pnt + 1, 0) {
                mul(res, res, k);
                if ((n >> p) & 1) {
                    per(i, k, 0) res[i + 1] = res[i]; res[0] = 0;
                    rep(j, 0, SZ(v)) res[v[j]] = (res[v[j]] - res[k] * val[v[j]]) % mod;
                }
            }
            rep(i, 0, k) ans = (ans + res[i] * b[i]) % mod;
            if (ans < 0) ans += mod;
            return ans;
        }
        VI BM(VI s) {
            VI C(1, 1), B(1, 1);
            int L = 0, m = 1, b = 1;
            rep(n, 0, SZ(s)) {
                LL d = 0;
                rep(i, 0, L + 1) d = (d + (LL)C[i] * s[n - i]) % mod;
                if (d == 0) ++m;
                else if (2 * L <= n) {
                    VI T = C;
                    LL c = mod - d * power(b, mod - 2) % mod;
                    while (SZ(C) < SZ(B) + m) C.pb(0);
                    rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % mod;
                    L = n + 1 - L; B = T; b = d; m = 1;
                } else {
                    LL c = mod - d * power(b, mod - 2) % mod;
                    while (SZ(C) < SZ(B) + m) C.pb(0);
                    rep(i, 0, SZ(B)) C[i + m] = (C[i + m] + c * B[i]) % mod;
                    ++m;
                }
            }
            return C;
        }
        int gao(VI a, LL n) {
            VI c = BM(a);
            c.erase(c.begin());
            rep(i, 0, SZ(c)) c[i] = (mod - c[i]) % mod;
            return solve(n, c, VI(a.begin(), a.begin() + SZ(c)));
        }
    };
    //用法vector<int>v;
    //打表填系数递推
    //linear_seq::gao(v, n - 1)
    

    字符串

    马拉车

    struct Manacher {
        int p[maxn << 1], str[maxn << 1];
        bool check(int x) {
            return x - (x & -x) == 0;
        }
        bool equal(int x, int y) {
            if ((x & 1) != (y & 1)) return false;
            return (x & 1) || (check(mask[x >> 1]) && check(mask[y >> 1]) && str[x] == str[y]);
        }
        int solve(int len) {
            int max_right = 0, pos = 0, ret = 0;
            for (int i = 1; i <= len; i++) {
                p[i] = (max_right > i ? std::min(p[pos + pos - i], max_right - i) : 1);
                if ((i & 1) || check(mask[i >> 1])) {
                    while (equal(i + p[i], i - p[i])) p[i]++;
                    if (max_right < i + p[i]) pos = i, max_right = i + p[i];
                    ret += p[i] / 2;
                } else p[i] = 2;
            }
            return ret;
        }
    } manacher;
    

    图论

    三元环

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e5 + 10;
    vector<int> g[N];
    int deg[N], vis[N], n, m, ans;
    struct E { int u, v; } e[N * 3];
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1 ; i <= m ; ++ i) {
            scanf("%d%d", &e[i].u, &e[i].v);
            ++ deg[e[i].u], ++ deg[e[i].v];
        }
        for(int i = 1 ; i <= m ; ++ i) {
            int u = e[i].u, v = e[i].v;
            if(deg[u] < deg[v] || (deg[u] == deg[v] && u > v)) swap(u, v);
            g[u].push_back(v);
        }
        for(int x = 1 ; x <= n ; ++ x) {
            for(auto y: g[x]) vis[y] = x;
            for(auto y: g[x])
                for(auto z: g[y])
                    if(vis[z] == x)
                        ++ ans;
        }
        printf("%d
    ", ans);
    }
    

    小技巧

    二进制状态压缩

    [取出整数n在二进制表示下的第k位:(n>>k)&1\ 取出整数n在二进制表示下的第0 sim k-1位(后k位):n&((1<<k)-1)\ 把整数n在二进制表示下第k位取反:nquad xorquad(1<<k)\ 对整数n在二进制下表示的第k位赋值1:n|(1<<k)\ 对整数n在二进制表示下的第k为赋值0:n&(sim(1<<k))\ ]

    rope的用法

    头文件:#include <ext/rope>

    命名空间using namespace __gnu_cxx;

    定义:rope r;

    insert(pos, s)将字符串s插入pos位置

    erase(pos, num)从pos开始删除num个字符

    copy(pos, len, s)从pos开始len个字符用s代替

    substr(pos, len)提取pos开始的len个字符

    at(x)访问第x个元素

    每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi
  • 相关阅读:
    .NET CORE QuartzJob定时任务+Windows/Linux部署
    .NET CORE 数据保护
    Docker容器间通信
    Docker加载本地证书
    转载-AppDomain详解
    JMeter尝鲜
    从String类型发散想到的一些东西
    npm源管理
    一张脑图整理Docker常用命令
    构造管“生”对象?析构管“埋”对象?C++中构造析构还没整明白?
  • 原文地址:https://www.cnblogs.com/buerdepepeqi/p/10921470.html
Copyright © 2020-2023  润新知