zoukankan      html  css  js  c++  java
  • [单位根反演] HDU 7013 String Mod

    题目大意

    对于所有由前 (k) 个小写英文字母组成的长为 (L) 的字符串,设 (A[i][j]) 表示字符串中 a 的数量模 (n) 等于 (i),b 的数量模 (n) 等于 (j) 这样的字符串个数。输出矩阵 (A)(2leq kleq 26,1leq Lleq 10^{18},1leq nleq 500)

    题解

    设字符串中含有 (x) 个 a 和 (y) 个 b,对 (x,y) 进行枚举,有

    [A[i][j]=sum_{x=0}^Lsum_{y=0}^{L-x} [n|x-i][n|y-j]inom{L}{x}inom{L-x}{y}(k-2)^{L-x-y}\ ]

    考虑换掉艾弗森约定,可以使用单位根反演:

    单位根反演

    [forall k,[n|k]=frac{1}{n}sum_{i=0}^{n-1} omega_n^{ik} ]

    证明:

    1. (n|k) 时,(omega_n^{ik}=omega_n^0=1)(frac{1}{n}sum_{i=0}^{n-1}omega_n^{ik}=1=[n|k])

    2. (n mid k) 时,

    [frac{1}{n}sum_{i=0}^{n-1}omega_n^{ik}=frac{1}{n}cdotfrac{omega_n^{nk}-1}{omega_n^k-1}=frac{1}{n}cdotfrac{1-1}{omega_n^k-1}=0=[n|k] ]

    所以有

    [A[i][j]=sum_{x=0}^Lsum_{y=0}^{L-x} [n|x-i][n|y-j]inom{L}{x}inom{L-x}{y}(k-2)^{L-x-y}\ =sum_{x=0}^Lsum_{y=0}^{L-x} left(frac{1}{n}sum_{p=0}^{n-1}omega_n^{p(x-i)} ight)left(frac{1}{n}sum_{q=0}^{n-1}omega_n^{q(y-j)} ight)inom{L}{x}inom{L-x}{y}(k-2)^{L-x-y}\ =frac{1}{n^2}sum_{p=0}^{n-1}sum_{q=0}^{n-1}sum_{x=0}^Lsum_{y=0}^{L-x} omega_n^{p(x-i)}omega_n^{q(y-j)}inom{L}{x}inom{L-x}{y}(k-2)^{L-x-y}\ =frac{1}{n^2}sum_{p=0}^{n-1}sum_{q=0}^{n-1}sum_{x=0}^Lsum_{y=0}^{L-x} omega_n^{px}omega_n^{qy}omega_n^{-pi}omega_n^{-qj}inom{L}{x}inom{L-x}{y}(k-2)^L(k-2)^{-x}(k-2)^{-y}\ =frac{1}{n^2}sum_{p=0}^{n-1}sum_{q=0}^{n-1}omega_n^{-pi}omega_n^{-qj}sum_{x=0}^Lsum_{y=0}^{L-x} omega_n^{px}omega_n^{qy}inom{L}{x}inom{L-x}{y}(k-2)^{L-x-y}\ =frac{1}{n^2}sum_{p=0}^{n-1}sum_{q=0}^{n-1}omega_n^{-pi}omega_n^{-qj}sum_{x=0}^Linom{L}{x}omega_n^{px}sum_{y=0}^{L-x} inom{L-x}{y}(k-2)^{L-x-y}(omega_n^q)^y\ =frac{1}{n^2}sum_{p=0}^{n-1}sum_{q=0}^{n-1}omega_n^{-pi}omega_n^{-qj}sum_{x=0}^Linom{L}{x}(omega_n^q+k-2)^{L-x}(omega_n^p)^x\ =frac{1}{n^2}sum_{p=0}^{n-1}sum_{q=0}^{n-1}omega_n^{-pi}omega_n^{-qj}(omega_n^p+omega_n^q+k-2)^L ]

    (P(i,p)=omega_{n}^{-pi},Q(p,q)=(omega_n^p+omega_n^q+k-2)^L,R(q,j)=omega_n^{-qj})

    (A[i][j]=frac{1}{n^2}sum_{p=0}^{n-1}sum_{q=0}^{n-1}P(i,p)Q(p,q)R(q,j))

    可以作两次矩阵乘法得到答案。

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    const LL p = 1e9 + 9;
    
    LL qpow(LL b, LL n) {
        LL x = 1, Power = b % p;
        while (n) {
            if (n & 1) x = x * Power % p;
            Power = Power * Power % p;
            n >>= 1;
        }
        return x;
    }
    
    struct Matrix {
        LL a[502][502];
        int n;
        Matrix operator*(const Matrix& r) {
            Matrix res;
            res.n = n;
            memset(res.a, 0, sizeof(res.a));
            for (int k = 0;k < n;++k)
                for (int i = 0;i < n;++i)
                    for (int j = 0;j < n;++j)
                        res.a[i][j] = (res.a[i][j] + a[i][k] * r.a[k][j] % p) % p;
            return res;
        }
    };
    LL x[505], L;
    int q[505];
    Matrix ans, A, B, C;
    int T, k, n;
    
    void solve() {
        ans.n = A.n = B.n = C.n = n;
        LL g = qpow(13, (p - 1) / n);
        x[0] = 1;
        for (int i = 1;i < n;++i) x[i] = x[i - 1] * g % p;
        for (int i = 0;i < n;++i)
            for (int j = 0;j < n;++j) {
                A.a[i][j] = qpow(g, i * j);
                B.a[i][j] = qpow(x[i] + x[j] + k - 2, L);
            }
        C = A;
        for (int i = 0;i < n;++i)
            for (int j = 0;j < i;++j)
                swap(C.a[i][j], C.a[j][i]);
        ans = A * B;ans = ans * C;
        LL m = qpow(n * n, p - 2);
        for (int i = 1;i < n;++i) q[i] = n - i;
        for (int i = 0;i < n;++i) {
            for (int j = 0;j < n;++j) {
                printf("%lld", ans.a[q[i]][q[j]] * m % p);
                if (j < n - 1) printf(" ");
            }
            printf("
    ");
        }
        return;
    }
    
    int main() {
        scanf("%d", &T);
        while (T--) {
            scanf("%d%lld%d", &k, &L, &n);
            solve();
        }
        return 0;
    }
    
  • 相关阅读:
    SEO分享:我为什么会有这么多的优质外链资源?
    执行shell脚本提示“syntax error near unexpected token for((i=0;i&lt;$length;i++))”
    Codeforces Round #254 (Div. 2)D(预计)
    自己写配置文件
    软件測试基本方法(二)之白盒測试
    hdu 4638 Group
    影视集结号--首页
    2015阿里巴巴秋招在线笔试题
    php 抓取天气情况 www.weather.com.cn
    C语言中的enum(枚举)使用方法
  • 原文地址:https://www.cnblogs.com/AEMShana/p/15107346.html
Copyright © 2011-2022 走看看