首页 > 其他分享 >闲话 22.12.28

闲话 22.12.28

时间:2022-12-28 19:55:05浏览次数:57  
标签:infty frac int 闲话 sum 28 22.12 left mod

闲话

这篇写成闲话,主要是最近想推歌了(
《シャボン(肥皂泡)》 by 蜂屋ななし feat. 初音ミク
《イカサマダンス(欺诈舞蹈)》 by まふまふ feat. 鏡音リン
《Shamer》 by Chinozo feat. flower
就今天给我推的歌(
我记性留不到第二天(

线性规划先等一天(
咕了咕了!

关于 \(\text{Lonesum Matrix}\) 的讨论

又名 W2B。

\(\text{Lonesum Matrix}\) 计数

定义一个 \(n\times m\) 的 \(01\) 矩阵是 \(\text{Lonesum Matrix (LM)}\),当且仅当其能由行列和向量唯一地确定。行和向量是对每一行分别求得 \(1\) 的个数后按原顺序排列得到的 \(n\) 维向量,列和向量同理。

给定 \(n, m\),计数 \(n\times m\) 的 \(\text{LM}\) 个数。

我们将给出两种方案,其最终能得到相同的结果。

1. 组合意义

请和我默念:组合意义天地灭

我们考虑使用一些列向量来拼合一个 \(\text{LM}\) 非全 \(0\) 全 \(1\) 的部分。我们称拼合的矩阵为部分矩阵。
定义不合法分量为 \(\left[\ \begin{aligned} & 1 & 0 \\ & 0 & 1 \end{aligned}\ \right]\) 和 \(\left[\ \begin{aligned} & 0 & 1 \\ & 1 & 0 \end{aligned}\ \right]\)。
我们定义不合法的部分矩阵是存在不合法分量为子矩阵的部分矩阵。可以发现存在这样子矩阵的矩阵能够将对应子矩阵交换两行/列得到行列和向量相同的不同矩阵。

我们定义行/列的权值是本行/列中 \(1\) 的个数。容易发现在合法的部分矩阵中不会出现相同权的列向量。需要注意这里没有使用全 \(0\) 全 \(1\) 的列向量。
可以发现对行列进行重排不会改变其是否是 \(\text{LM}\),因为不合法分量是彼此镜像的。

随后就能计数了。
我们取得一个部分矩阵。假设这个部分矩阵由 \(k - 1\) 个列向量按权值降序组成,则每行的权值在 \([0, k)\) 之间,这就构成了 \(k\) 个等价类。对 \(k\) 个彼此不同的等价类放入 \(n\) 个行计数得到 \(k! {n \brace k}\)。
\(k - 1\) 个列的部分矩阵肯定是 \(k\) 个列的部分矩阵的子集,因此做容斥,系数是 \((-1)^{n + m}\)。
最后还需要确定 \(k - 1\) 个列的部分矩阵所能生成的矩阵数量。可以在最后加入一行全 \(1\),因此行权值在 \([0, k]\) 之间。有 \((k + 1)^m\) 种可能。

得到计数

\[\sum_{k=1}^n (-1)^{n + k} k! {n \brace k} (k + 1)^m \]

感觉不是那么好理解?看看下面?

2. 代数推导

请和我默念:组合意义天地灭,代数推导保平安。

当然需要声明的是:本方法来自 \(\text{A}\color{red}{\text{PJifengc}}\)
此外,本文部分内容完全来自于她解题时的想法与评价。

image
image

首先需要考虑的是不合法情况,即子矩阵出现不合法分量。然后设 \(f(n, m)\) 为 \(n \times m\text{ LM}\) 的数量。

首先钦定第一行选什么。然后发现顺序不重要,有 \(01\) 个数就行了。枚举 \(1\) 的数量。随后考虑如果第二行有一个数和第一行的数相同,那其他第二行对应第一行位置上数和第一行的数相同的数就必须和第二行这个数相同。这就等价于 \(0\) 或 \(1\) 必须有一个数和第一行完全一样,直接计数,减掉都一样的情况就行了。如果下面的每一行都满足这个条件,那这些行之间就不用再考虑了,直接拆成了子问题。

也就是说:

\[f(n, m) = \sum_{i=0}^{m}\sum_{j=0}^n \sum_{k = 0}^{n-j} (-1)^j \binom{m}{i}\binom{n-1}{j}\binom{n-1-j}{k} f(k, i) f(n - 1 - j - k, m - i) \]

到这一步就是 \(O(n^5)\) 的了,下面我们要把它用代数工业优化成 \(O(n\log n)\)。其实还挺顺的。考虑生成这个 \(f\),看到二项式系数后采用 EGF。设

\[F(x, y) = \sum_{i=0}^{\infty} \sum_{j=0}^{\infty} f(i, j)\frac{x^i}{i!}\frac{y^j}{j!} \]

暴力带入后拆解各项系数可以得到一长串式子。首先这应当是 \(F^2\) 的形式,但你发现系数在 \(x\) 方向有偏移,因此需要对 \(x\) 求积分,发现系数也对了。但是 \(x = 0\) 的地方缺了一项,加入 \(e^y\) 即可。

也就是说

\[F(x, y) = \int F(x, y) \text d x + e^y \]

解微分方程可得

\[F(x, y) = (e^{-x} + e^{- y} - 1)^{-1} \]

我们需要的就是提取 \(F\) 的 \([x^ny^m / n!m!]\) 次项。这时候你可能会想 “不会!”、”我要是会做我就会做了!”、“麻了,这个式子我拆拆就拆回最开始写的式子了”、”感觉封闭形式推了个寂寞“……。
但是不要担心,万事皆有可能!我们最需要的其实是良好的心态——

image

让我们从最简单的手段开始:

\[\begin{aligned} &\left[\frac{x^ny^m}{n!m!}\right] (e^{-x} + e^{- y} - 1)^{-1} \\ = & \ \left[\frac{x^ny^m}{n!m!}\right] \sum_{i=0}^{\infty} \binom{-1}{i} (e^{-x} - 1)^i e^{-y( - 1 - i)} \qquad & (广义二项式定理) \\ = & \ \left[\frac{x^ny^m}{n!m!}\right] \sum_{i=0}^{\infty} (-1)^i (e^{-x} - 1)^i e^{y(i + 1)} \qquad & (上指标反转) \\ = & \ \left[\frac{x^ny^m}{n!m!}\right] \sum_{i=0}^{\infty} (-1)^i (e^{-x} - 1)^i \sum_{j=0}^{\infty} \frac{y^j(i + 1)^j}{j!} \qquad& (e^x\ 的 \text{ EGF } 形式) \\ = & \ \left[\frac{x^ny^m}{n!m!}\right] \sum_{j=0}^{\infty} \left(\sum_{i=0}^{\infty} (-1)^i (e^{-x} - 1)^i (i + 1)^j\right) \frac{y^j}{j!} \\ = & \ \left[\frac{x^n}{n!}\right] \sum_{i=0}^{\infty} (-1)^i (e^{-x} - 1)^i (i + 1)^j \end{aligned}\]

我们已经去掉了一个变量了!只剩一个了!
image

我们发现,\((e^{-x} - 1)^i\) 这样的形式有些眼熟,令人想起第二类斯特林数的 EGF。考虑配凑出形式。

\[\begin{aligned} &\left[\frac{x^n}{n!}\right] \sum_{i=0}^{\infty} (-1)^i (i + 1)^j (e^{-x} - 1)^i \\ = & \ \left[\frac{x^n}{n!}\right] \sum_{i=0}^{\infty} (-1)^i (i + 1)^j i! \frac{(e^{-x} - 1)^i}{i!} \qquad & (如上方法配凑) \\ = & \ \left[\frac{x^n}{n!}\right] \sum_{i=0}^{\infty} (-1)^i (i + 1)^j i! \sum_{j=i}^{\infty} {j \brace i} \frac{(-x)^j}{j!} \qquad & (展开为 \ \text{EGF}) \\ = & \ \left[\frac{x^n}{n!}\right] \sum_{j=0}^{\infty} \sum_{i=0}^{j} (-1)^i (i + 1)^j i! {j \brace i} \frac{(-x)^j}{j!} \\ = & \ \left[\frac{x^n}{n!}\right] \sum_{j=0}^{\infty} \left( \sum_{i=0}^{j} (-1)^{i+j} i! {j \brace i}(i + 1)^j \right) \frac{x^j}{j!} \\ = & \ \sum_{i=0}^{j} (-1)^{i+n} i! {n \brace i}(i + 1)^n \end{aligned}\]

我们成功了!形式和组合方法得到的完全相同!让我们听听 APJifengc 先生是如何想的吧:
image

image

image

真是太强了!

好到这里两种做法就都告一段落了。可以使用生成函数法求得第二类斯特林数,随后模拟即可。总时间复杂度为 \(O(n\log n)\)。

最后需要说明的是,\(f(n, m)\) 即为 \(B_n^{(-m)}\),多项式伯努利数,A099594

code
#include <bits/stdc++.h>
using namespace std; using pii = pair<int,int>; using vi = vector<int>; using vp = vector<pii>; using ll = long long; 
using ull = unsigned long long; using db = double; using ld = long double; using lll = __int128_t;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
template <typename T> T rand(T l, T r) { return uniform_int_distribution<T>(l, r)(rnd); }
template <typename T> void get(T & x) {
	x = 0; char ch = getchar(); bool f = false; while (ch < '0' or ch > '9') f = f or ch == '-', ch = getchar();
	while ('0' <= ch and ch <= '9') x = (x << 1) + (x << 3) + ch - '0', ch = getchar(); f && (x = -x); 
} template <typename T, typename ... Args> void get(T & a, Args & ... b) { get(a); get(b...); }
#define iot ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#define timer cerr << 1. * clock() / CLOCKS_PER_SEC << '\n';
template <typename T1, typename T2> T1 min(T1 a, T2 b) { return a < b ? a : b; }
template <typename T1, typename T2> T1 max(T1 a, T2 b) { return a > b ? a : b; }
#define file(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define ufile(x) 
#define rep(i,s,t) for (register int i = (s), i##_ = (t) + 1; i < i##_; ++ i)
#define pre(i,s,t) for (register int i = (s), i##_ = (t) - 1; i > i##_; -- i)
#define Aster(i, s) for (int i = head[s], v; i; i = e[i].next)
#define all(s) s.begin(), s.end()
#define eb emplace_back
#define pb pop_back
#define em emplace
const int N = 3e6 + 10, mod = 998244353, g = 3;
using poly = vector<int>;
int n, m, ans;
poly F, G; 

int qp(int a, int b) {
    int ret = 1;
    while (b) {
        if (b & 1) ret = 1ll * a * ret % mod;
        a = 1ll * a * a % mod;
        b >>= 1;
    } return ret;
} int invg = qp(g, mod - 2);

int btrs[N];
int initrs(int mx) {
    int lim = 1;
    while (lim <= mx) lim <<= 1;
    for (int i = 0; i < lim; ++ i)
        btrs[i] = (btrs[i >> 1] >> 1) | ((i & 1) ? lim >> 1 : 0);
    return lim;
}

void NTT(poly& a, int len, const int typ) {
    a.resize(len);
    for (int i = 0; i < len; ++ i) if (i < btrs[i]) swap(a[i], a[btrs[i]]);
    for (int mid = 1, t, wn; mid < len; mid <<= 1) {
        wn = qp(typ == 1 ? g : invg, (mod - 1) / (mid << 1));
        for (int j = 0, w = 1; j < len; j += (mid << 1)) {
            w = 1;
            for (int k = 0; k < mid; ++ k, w = 1ll * w * wn % mod) {
                t = 1ll * w * a[j + k + mid] % mod;
                a[j + k + mid] = a[j + k] - t + mod; if (a[j + k + mid] >= mod) a[j + k + mid] -= mod;
                a[j + k] += t; if (a[j + k] >= mod) a[j + k] -= mod;
            }
        }
    } if (typ == 1) return;
    int inv = qp(len, mod - 2);
    for (int i = 0; i < len; ++ i) a[i] = 1ll * a[i] * inv % mod;
}

poly A, B;
poly mul(const poly &a, const poly &b) {
    int o = a.size() + b.size() - 1, len = initrs(a.size() + b.size() - 1);
    A = a, B = b;
    NTT(A, len, 1), NTT(B, len, 1);
    for (int i = 0; i < len; ++ i) A[i] = 1ll * A[i] * B[i] % mod;
    NTT(A, len, 0);
    A.resize(o);
    return A;
}

int fac[N], inv[N];
void init(int M) {
    fac[0] = fac[1] = inv[0] = inv[1] = 1;
    rep(i,2,M) inv[i] = 1ll * (mod - mod / i) * inv[mod % i] % mod;
    rep(i,1,M) fac[i] = 1ll * fac[i - 1] * i % mod, 
        inv[i] = 1ll * inv[i - 1] * inv[i] % mod;
}

signed main() {
    file(w2b);
    cin >> n >> m;
    init(max(n, m)); 
    F.resize(n + 1), G.resize(n + 1);
    rep(i,0,n) F[i] = 1ll * qp(i, n) * inv[i] % mod, G[i] = ((i & 1) ? mod - inv[i] : inv[i]);
    F = mul(F, G);
    rep(i,1,n) {
        int t = 1ll * fac[i] * F[i] % mod * qp(i + 1, m) % mod;
        ans += ((n + i) & 1 ? mod - t : t);
        if (ans >= mod) ans -= mod;
    } cout << ans << '\n';
}

标签:infty,frac,int,闲话,sum,28,22.12,left,mod
From: https://www.cnblogs.com/joke3579/p/chitchat221228.html

相关文章

  • 【221228-2】三角形ABC中,角A=45度,AD垂直BC于D,BD=3,DC=2. 求AB长度?(使用三角函数或相似三
    ......
  • 日记-221228
    日记-221228地点:嘉兴状态:良好Todo:做饭每日一题小记第一次做饭开心,第一次写日记,今天和咱姐讲了讲zzy的事,我也不知道最后结局这么样,但绝对要努力,去改变,去奋斗。能......
  • déce. 28 两道题
    https://www.luogu.com.cn/problem/P2820菜题一天做一道还是太浪费时间了最小生成树,输入数据保证边权为正但是原始图可能不连通,生成树要保证图的不连通性问题不大,建立"......
  • 2022.12.28笔记
    1、父组件调用子组件中的方法【函数】:(1)通过ref直接调用子组件的方法;参考链接:https://www.cnblogs.com/effortandluck/p/16355992.html 2、音频属性的认识;  ......
  • 学习笔记282—SD与SEM有区别吗
    SD是标准偏差,反映的是样本变量值的离散程度。SEM是标准误差,反映的是样本均数之间的变异。SD为样本标准差,根据标准差SD能反映变量值的离散程度。正负值就是在计算好的SD......
  • POJ 2287 Tian Ji -- The Horse Racing(贪心 记忆化搜索)
    POJ2287TianJi--TheHorseRacing题意​ 田忌赛马的故事,相信大家都知道,不多赘述。田忌和国王各有n匹马,每匹马都有一个能力值,两匹马赛跑的话,能力值高者胜。田忌每......
  • 12_28
    shoutforhelp呼救过去进行时was/were+v-ing;过去某一时刻或者某一时间正在进行/发生的动作eg:WewerewatchingTVfrom7to9lastnight.昨天晚上我们在看电......
  • PLSQL:ora-28534 多机种服务预处理错误
     ora-28534多机种服务预处理错误通过oracle连sqlserver,查询sqlserver里的某张表没问题,但向这张表插数据的时候报“ora-28534多机种服务预处理错误”. 原因: SQLSER......
  • MIT 6.828 Homework: biggers files for xv6
    任务概述在这个作业中,需要增加xv6系统允许的文件大小。当前的xv6文件大小被限制为140扇区(sectors),因为xv6的索引节点(innode)包含了12个“直接的”块(bl......
  • Waves 14 Complete for Mac(Waves混音效果全套插件) v2022.12.27激活版
    Waves14mac中文版是一款混响功能强大的音频编辑后期混音插件套装!全新版本的Waves14Complete拥有需要新的功能,我们最受欢迎的压缩机增加了混合和微调旋钮在API2500、CLA......