Solution -「NOI 2017」「洛谷 P3824」泳池
\(\mathscr{Description}\)
Link.
给定 \(n,k,p\), 求在一个 \(\infty\times n\) 的矩阵中, 每个位置的值以 \(p\) 的概率为 \(0\), \(1-p\) 的概率为 \(1\) 时, 以第一行为边界的最大全 \(0\) 子矩阵大小恰好为 \(k\) 的概率. 答案模 \(998244353\).
\(\mathscr{Solution}\)
把 \(k\) 容斥成 \(\le\). 令 \(f(i)\) 表示考虑了前 \(i\) 列, 所有合法子矩阵 \(\le k\) 的概率, \(g(i,j)\) 表示一个 \(i\) 列的矩阵, 第一个 \(1\) 出现在第 \(j\) 行, 且 \(\infty\times i\) 里不存在非法子矩阵的概率. 那么
\]
先来考察 \(g\). 枚举第 \(j\) 行上第一个 \(1\):
\]
处理 \(g(i,j)\) 关于 \(j\) 的后缀和 \(h(i,j)\), 不难做到 \(\mathcal O(k^2\log k)\) 转移. 当然可以用多项式算法优化.
此后, 我们得到了一个常系数齐次线性递推:
\]
用 LSB-first, 暴力算乘法; 或者用 Fiduccia 都行. 复杂度 \(\mathcal O(k^2\log k)\).
\(\mathscr{Code}\)
/* Clearink */
#include <cstdio>
#include <cstring>
#define rep( i, l, r ) for ( int i = l, rep##i = r; i <= rep##i; ++i )
#define per( i, r, l ) for ( int i = r, per##i = l; i >= per##i; --i )
const int MAXK = 1000, MOD = 998244353;
int n, m, p, pwr[MAXK + 5];
int f[MAXK + 5][MAXK + 5], A[MAXK * 2 + 5], F[MAXK * 2 + 5];
inline void subeq( int& a, const int b ) { ( a -= b ) < 0 && ( a += MOD ); }
inline int sub( int a, const int b ) { return ( a -= b ) < 0 ? a + MOD : a; }
inline void addeq( int& a, const int b ) { ( a += b ) >= MOD && ( a -= MOD ); }
inline int mul( const long long a, const int b ) { return int( a * b % MOD ); }
inline int mpow( int a, int b ) {
int ret = 1;
for ( ; b; a = mul( a, a ), b >>= 1 ) ret = mul( ret, b & 1 ? a : 1 );
return ret;
}
inline int dp( const int i, const int j, const int m ) {
if ( !j ) return 1;
if ( i * j > m ) return 0;
int& cur = f[i][j];
if ( ~cur ) return cur;
cur = mul( pwr[j], dp( i + 1, j, m ) );
rep ( k, 1, j ) {
addeq( cur, mul( mul( pwr[k - 1], sub( 1, p ) ),
mul( dp( i + 1, k - 1, m ), dp( i, j - k, m ) ) ) );
}
return cur;
}
inline void polyMul( const int n, const int m, int& r,
const int* u, const int* v, int* w ) {
static int tmp[MAXK * 2 + 5];
rep ( i, 0, n + m ) tmp[i] = 0;
rep ( i, 0, n ) rep ( j, 0, m ) addeq( tmp[i + j], mul( u[i], v[j] ) );
r = n + m;
rep ( i, 0, r ) w[i] = tmp[i];
}
inline void polyMod( int& n, const int m, int* u, const int* v ) {
per ( i, n, m ) {
if ( !u[i] ) continue;
int coe = u[i];
rep ( j, 0, m ) subeq( u[i - j], mul( coe, v[m - j] ) );
}
n = n < m - 1 ? n : m - 1;
while ( n && !u[n] ) --n;
}
inline int calc( int n, const int m ) {
static int Q[MAXK * 2 + 5], S[MAXK * 2 + 5], G[MAXK * 2 + 5];
memset( Q, 0, sizeof Q );
memset( S, 0, sizeof S );
memset( G, 0, sizeof G );
int lq = m, ls = 0, lg = 1;
Q[m] = 1;
rep ( i, 0, m - 1 ) Q[m - i - 1] = sub( 0, A[i] );
S[0] = G[1] = 1;
for ( ; n; n >>= 1 ) {
if ( n & 1 ) {
polyMul( ls, lg, ls, S, G, S );
polyMod( ls, lq, S, Q );
}
polyMul( lg, lg, lg, G, G, G );
polyMod( lg, lq, G, Q );
}
int ret = 0;
rep ( i, 0, m - 1 ) addeq( ret, mul( F[i], S[i] ) );
return ret;
}
inline int solve( int m ) {
memset( f, 0xff, sizeof f );
dp( 0, m, m );
memset( F, 0, sizeof F ), memset( A, 0, sizeof A );
F[0] = 1, A[0] = sub( 1, p );
rep ( i, 1, m ) {
F[i] = f[0][i];
A[i] = mul( f[1][i], mul( sub( 1, p ), pwr[i] ) );
}
return calc( n, m + 1 );
}
int main() {
int x, y;
scanf( "%d %d %d %d", &n, &m, &x, &y ), p = mul( x, mpow( y, MOD - 2 ) );
pwr[0] = 1;
rep ( i, 1, m ) pwr[i] = mul( pwr[i - 1], p );
printf( "%d\n", sub( solve( m ), solve( m - 1 ) ) );
return 0;
}
Solution -「NOI 2017」「洛谷 P3824」泳池的更多相关文章
- 「区间DP」「洛谷P1043」数字游戏
「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...
- [CodePlus 2017 11月赛&洛谷P4058]木材 题解(二分答案)
[CodePlus 2017 11月赛&洛谷P4058]木材 Description 有 n棵树,初始时每棵树的高度为 Hi ,第 i棵树每月都会长高 Ai.现在有个木料长度总量为 S的订单, ...
- Solution -「JSOI 2019」「洛谷 P5334」节日庆典
\(\mathscr{Description}\) Link. 给定字符串 \(S\),求 \(S\) 的每个前缀的最小表示法起始下标(若有多个,取最小的). \(|S|\le3\time ...
- Solution -「洛谷 P4372」Out of Sorts P
\(\mathcal{Description}\) OurOJ & 洛谷 P4372(几乎一致) 设计一个排序算法,设现在对 \(\{a_n\}\) 中 \([l,r]\) 内的元素排 ...
- Solution -「POI 2010」「洛谷 P3511」MOS-Bridges
\(\mathcal{Description}\) Link.(洛谷上这翻译真的一言难尽呐. 给定一个 \(n\) 个点 \(m\) 条边的无向图,一条边 \((u,v,a,b)\) 表示从 ...
- Solution -「APIO 2016」「洛谷 P3643」划艇
\(\mathcal{Description}\) Link & 双倍经验. 给定 \(n\) 个区间 \([a_i,b_i)\)(注意原题是闭区间,这里只为方便后文描述),求 \(\ ...
- 「洛谷 P1801」黑匣子
好像很久没有更过博客了,因为博主这几周很忙.其实是在搞颓. 题意很难懂,所以就不重复了.其实是懒. 一眼看上去这是个 \(Splay\) 裸题,直接插入一个数,查询区间第 \(K\) 大,但是这样太不 ...
- 「洛谷4197」「BZOJ3545」peak【线段树合并】
题目链接 [洛谷] [BZOJ]没有权限号嘤嘤嘤.题号:3545 题解 窝不会克鲁斯卡尔重构树怎么办??? 可以离线乱搞. 我们将所有的操作全都存下来. 为了解决小于等于\(x\)的操作,那么我们按照 ...
- 「洛谷3338」「ZJOI2014」力【FFT】
题目链接 [BZOJ] [洛谷] 题解 首先我们需要对这个式子进行化简,否则对着这么大一坨东西只能暴力... \[F_i=\sum_{j<i} \frac{q_iq_j}{(i-j)^2}-\s ...
- 「BZOJ2733」「洛谷3224」「HNOI2012」永无乡【线段树合并】
题目链接 [洛谷] 题解 很明显是要用线段树合并的. 对于当前的每一个连通块都建立一个权值线段树. 权值线段树处理操作中的\(k\)大的问题. 如果需要合并,那么就线段树暴力合并,时间复杂度是\(nl ...
随机推荐
- HTML5+CSS3+JavaScript网页实战
1. HTML5基础 HTML5,作为构建和呈现网页内容的标准标记语言,带来了许多革命性的变化.它不仅提供了更加语义化的标签,使得网页内容更具可读性和可访问性,还增加了对多媒体的原生支持,无需依赖第三 ...
- Exadata系列之配置利器OECA
Oracle Exadata Configuration Assistant (OECA) 是一款简便的配置工具,用于快速生成Exadata系统的推荐配置方案.它根据用户的需求和负载特点,自动推荐合适 ...
- 【一步步开发AI运动小程序】八、利用body-calc进行姿态识别
随着人工智能技术的不断发展,阿里体育等IT大厂,推出的"乐动力"."天天跳绳"AI运动APP,让云上运动会.线上运动会.健身打卡.AI体育指导等概念空前火热.那 ...
- 鸿蒙hvigor构建任务依赖与生命周期简介
Hivgor脚本文件 在构建的生命周期中Hvigor使用两个脚本文件来完成插件.任务以及生命周期hook的注册: hvigorconfig.ts:此文件在整个项目中只有根目录下存在一份,不是构建必须的 ...
- VUE懒加载的table前端搜索
// 前端搜索 fliterData() { const search = this.search if (search) { this.blist = this.list.filter(item = ...
- select2的搜索框不能输入内容
select2的搜索框不能输入内容 原因:原来是模态对话框强制使自己处于焦点状态,导致select2的搜索框无法获取焦点所致. 解决办法:在初始化中重写模态对话框的enforceFocus函数 $.f ...
- linux bash shell 中的单引号和双引号
摘抄自:ABS_CN 当要引用一个变量的值时,一般推荐使用双引号.使用双引号除了变量名[2]前缀($).后引符(`)和转义符(\)外,会使shell不再解释引号中其它所有的特殊字符.[3] 用双引号时 ...
- Python之时间日期操作
常用时间操作的函数汇总, 涵盖 常用的time datetime 1.计算两个日期相差天数 import datetime str1 = '2021-10-20' str2 = '2021-10- ...
- Docker之磁盘清理
Docker 很占用空间,每当我们运行容器.拉取镜像.部署应用.构建自己的镜像时,我们的磁盘空间会被大量占用. 如果你也被这个问题所困扰,咱们就一起看一下 Docker 是如何使用磁盘空间的,以及如何 ...
- ubuntu 下的 nslookup 命令利用 127.0.0.53 查询主机名失败,而使用网关则正常的问题
遇到一个奇怪的问题,ubuntu 下使用 KRDC 远程访问局域网主机时,连接主机名失败,使用 ip 则正常.通过 nslookup 命令发现,局域网主机名没有被正确解析(使用的是默认的 127.0. ...