• 自嗨测试赛2


    A 任意模数多项式乘法逆

    题目大意 : 求一个多项式乘法逆的n次项系数

    • 看到这个题目和题面还以为是一个板子(而且还忘了怎么打),于是心里强烈谴责了出题人TheSure

    • 后来发现不是这样,给出的多项式最高次不超过10,于是10n就能跑过去了

    • 有亿点卡常,用矩阵快速幂的话可以极快得通过(不过我没写)

    Code

    Show Code
    #include <cstdio>
    
    using namespace std;
    const int N = 1e7;
    
    int n, k, M, f[N], a[15];
    
    int main() {
        freopen("poly.in", "r", stdin);
        freopen("poly.out", "w", stdout);
        scanf("%d%d%d", &n, &k, &M); f[0] = 1;
        for (int i = 1; i <= k; ++i)
            scanf("%d", &a[i]);
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= k && i - j >= 0; ++j) {
                long long x = 1ll * f[i-j] * a[j];
                if (x >= M) x %= M;
                if ((f[i] += x) >= M) f[i] -= M;
            }
            f[i] = M - f[i];
        }
        printf("%d
    ", f[n]);
        return 0;
    }
    

    B 明明的随机数

    题目大意 : 生成有一个n行m列的矩阵,每个数为不超过c的正整数,行列去重之后剩下k1行k2列,问有多少种方案

    • 设f[i]表示i行无限制,k2列两两不同的方案数,第一列有 (c_i) 中选法,以后的每一列都不能选前面的选法,所以可知

    [f[i]=prod_{j=0}^{k2}c^i-j ]

    • 设g[i]表示i行,k2列都两两不同的方案数, (left { ^n_k ight })表示第二类斯特林数

    [f[i]=sum_{j=1}^{i}left { ^i_j ight }g[j] ]

    • 这个式子的含义大概就是枚举有多少种不同的,然后求个和,也不知道该咋解释

    • 根据斯特林反演的式子可得

    [g[i]=sum_{j=1}^{i}(-1)^{i-j}left { ^i_j ight }f[j] ]

    • 于是答案就出来了

    [ans=g[k1]left { ^n_{k1} ight }left { ^m_{k2} ight } ]

    • 求f[i]的时候可以 O(k2),求g[k1]用时O(k),第二类斯特林数可以用O(n)的通项公式求

    Code

    Show Code
    #include <cstdio>
    
    using namespace std;
    const int N = 3005, M = 998244353;
    
    int read(int x = 0, int f = 1, char c = getchar()) {
        for (; c < '0' || c > '9'; c = getchar()) if (c == '-') f = -1;
        for (; c >='0' && c <='9'; c = getchar()) x = x * 10 + c - '0';
        return x * f;
    }
    
    int T, n, m, k1, k2, c, s[N][N], fac[N], inv[N], ans;
    
    int Pow(int a, int k, int ans = 1) {
        for (; k; k >>= 1, a = 1ll * a * a % M)
            if (k & 1) ans = 1ll * ans * a % M;
        return ans;
    }
    
    void Init(int n) {
        s[0][0] = fac[0] = 1;
        for (int i = 1; i <= n; ++i) 
            fac[i] = 1ll * fac[i-1] * i % M;
        inv[n] = Pow(fac[n], M - 2);
        for (int i = n; i >= 1; --i)
            inv[i-1] = 1ll * inv[i] * i % M;
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= i; ++j)
                s[i][j] = (s[i-1][j-1] + 1ll * (i - 1) * s[i-1][j]) % M;
    }
    
    int S(int n, int k) {
        int ans = 0;
        for (int i = 0; i <= k; ++i)
            ans = (ans + 1ll * Pow(i, n) * inv[i] % M * inv[k-i] % M * ((k - i) & 1 ? -1 : 1) + M) % M;
        return ans;
    }
    
    int main() {
        freopen("random.in","r",stdin);
        freopen("random.out","w",stdout);
        scanf("%d", &T); Init(N - 1);
        while (T--) {
            scanf("%d%d%d%d%d", &n, &m, &k1, &k2, &c);
            int p = 1; ans = 0;
            for (int i = 1; i <= k1; ++i) {
                int f = 1; p = 1ll * p * c % M;
                for (int j = 0; j < k2; ++j)
                    f = 1ll * f * (p - j) % M;
                ans = (ans + 1ll * s[k1][i] * f % M * ((k1 - i) & 1 ? -1 : 1) + M) % M;
            }
            printf("%lld
    ", 1ll * ans * S(n, k1) % M * S(m, k2) % M);
        }
        return 0;
    }
    

    C 凯爹博弈 (Unaccepted)

    题目大意 :

    Code

    Show Code
  • 相关阅读:
    扩展kmp
    计算几何板子
    组合数板子
    SecureML: A System for Scalable Privacy-Preserving Machine Learning 论文笔记
    mac任务管理器快捷键
    后缀数组
    poj 1144 Network【图的割点】模板
    CSU 1162【Balls in the Boxes】
    CSU 1111【三家人】数学题
    P1330 封锁阳光大学【二分染色】
  • 原文地址:https://www.cnblogs.com/shawk/p/14507472.html
Copyright © 2020-2023  润新知