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 ...
随机推荐
- 内核源码+vscode+bear+clang实现函数任意跳转,无缝跳转,无缝阅读,无缝开发
一.准备工作 1.内核源码版本选择 务必有一份能编译通过的<内核源码>,本次选择5.10版本的. #说明:5.10版本的<内核源码>里,在 scripts/clang-tool ...
- AT开发FOTA远程升级:Air780EP低功耗4G模组
针对客户朋友的应用反馈,特本篇文章:基于Air780EP模组AT开发的FOTA远程升级指南. AT版本的远程升级主要是对AT固件版本进行升级,实际方式为通过合宙官方IoT平台升级或者使用自己搭建的 ...
- Chrome控制台中network底部概要参数
概要参数 1.requests => 资源请求总数: 2.transferred => 网络加载资源大小: 3.resources => 页面所有资源总大小(包含网络资源.浏览器缓存 ...
- 我的neovim配置
init.vim " Vim with all enhancements "文件管理器,我想试一下ranger syntax enable syntax on let maplea ...
- HTTP请求与响应格式解析
HTTP是Web浏览器与Web服务器之间通信的标准协议,HTTP指明了客户端如何与服务器建立连接,如果从服务器请求数据,服务器如何响应请求,关闭连接.HTTP是使用TCP/IP协议进行传输数据的,也 ...
- JVM 核心技术
1.Java代码编译和执行的整个过程: 2. JVM内存管理及垃圾回收机制: 先看图, 二.Java代码编译和执行的整个过程 Java代码编译是由Java源码编译器来完成,流程图如下所示: Java ...
- 使用 Antlr 处理文本
高 尚 (gaoshang1999@163.com), 软件工程师, 中国农业银行软件开发中心 简介: Antlr 是一个基于 Java 开发的功能强大的语言识别工具,其主要功能原本是用于识别编程语言 ...
- React使用useRef调用子组件方法
前情 公司前端主技术栈是react系,最近在提取组件的时候想到vue可以通过ref获取子组件,再调用子组件的方法,于是想在react中实现同样效果. 实现原理 父组件调用useRef获取ref对象,再 ...
- 07C++选择结构(1)——教学
一.基础知识 1.关系运算符 因为我们要对条件进行判断,必然会用到关系运算符: 名称 大于 大于等于 小于 小于等于 等于 不等于 符号 > >= < <= == != 关系表 ...
- 鸿蒙应用开发从入门到入行 - 篇2:HarmonyOS开发快速基础入门
鸿蒙应用开发从入门到入行 第二天 - 开发工具与基础组件 导读:在本篇文章里,您将掌握鸿蒙开发工具DevEco的基本使用.ArkUI里的基础组件,并通过制作一个简单界面掌握使用 鸿蒙开发工具 - De ...