2023NOIP A层联测23-涂鸦

有一面由 n × m n\times m n×m 个格子组成的墙,每个格子要么是黑色,要么是白色。你每次将会进行这样的操作:等概率随机选择一个位置 ( x , y ) (x,y) (x,y),和一个颜色 c c c(黑色或者白色)( 1 ≤ x ≤ n , 1 ≤ y ≤ m 1≤x≤n,1≤y≤m 1xn,1ym,任意 ( x , y , c ) (x,y,c) (x,y,c) 的组合选择它的概率均为 1 2 ∗ n ∗ m \frac1{2∗n∗m} 2nm1),然后将在 ( x , y ) (x,y) (x,y) 左上⻆的所有格子的颜色涂成 c c c。即将所有满足 1 ≤ x ′ ≤ x , 1 ≤ y ′ ≤ y 1≤x′≤x,1≤y′≤y 1xx,1yy ( x ′ , y ′ ) (x′,y′) (x,y) 格子上的颜色涂成 c c c。这次操作的代价为涂的格子的数量,即 x × y x\times y x×y。给定初始状态和终止状态,问期望要花费多少代价才能将墙面从初始状态涂成终止状态。答案模 998244353 998244353 998244353

n , m ≤ 5 n,m\le5 n,m5


先考虑朴素的 dp,对墙上的每个格子进行状态压缩,总共有 2 n m 2^{nm} 2nm 个状态,设 f i f_i fi 表示状态 i i i 期望还要花费多少代价才能到达最终状态。转移为
f i = ∑ f j + w 2 n m f_i=\sum\dfrac{f_j+w}{2nm} fi=2nmfj+w

其中 j j j 表示一个格子的左上角都涂成黑色或白色所得到的状态, w w w 是涂一次颜色的代价。

这是有后效性 dp,可以高斯消元解决,时间复杂度 O ( 2 3 n m ) O(2^{3nm}) O(23nm),可以得到 60pts。

下面考虑减少状态。

考虑一个状态,若一个格子的颜色与最终状态的颜色不同,则这个点后面一定会修改,其左上角的点同样,所以这些点的颜色是什么就不重要了,反正后面都要被改。记 p i , j p_{i,j} pi,j 表示状态中坐标为 ( i , j ) (i,j) (i,j) 的点的颜色是否(1/0)与终止状态一样,通过模拟可以发现, p p p 数组中构成 1 1 1 的元素是类似阶梯的形状。如下图,圆点表示在这个格子颜色与最终状态的不一样,矩形表示
范围内的格子要被修改,红色部分就是 p i , j p_{i,j} pi,j 1 1 1 的部分。

在这里插入图片描述
称这个矩阵为阶梯矩阵,原来的状态称为 01 矩阵。

那么,所有的 01 矩阵都能唯一转化为一个阶梯矩阵,所以只需将原来的状态换成新的阶梯状态进行高斯消元即可。

而阶梯状态是不多的,只有 ( n + m n ) \binom{n+m}{n} (nn+m) 种,下面证明。

考虑每一行,看每行红色部分的格子数量,容易发现它们是有单调性的,设格子数量为 i i i 的行数为 x i x_i xi,即方案就是求 ∑ i = 0 n x i = m \sum\limits_{i=0}^nx_i=m i=0nxi=m 的解的个数,这是组合数学的经典问题,易证。

( n + m n ) \binom{n+m}{n} (nn+m) 最大也就 ( 10 5 ) = 252 \binom{10}{5}=252 (510)=252,高斯消元绰绰有余。

实现上,可以用 dfs 求出阶梯矩阵的状态和个数,01 矩阵转换成阶梯矩阵直接暴力枚举(时间充裕)每个点,若颜色不相同就直接对左上角修改。高斯消元要写模意义下的,我的实现直接用快速幂求逆元。

总的时间复杂度为 O ( ( n + m n ) 3 + ( n + m n ) n 3 m 3 ) O\left(\binom{n+m}{n}^3+\binom{n+m}{n}n^3m^3\right) O((nn+m)3+(nn+m)n3m3)

具体实现参照代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=998244353;
const int N=260;
ll a[N][N],val[N];
int fr[N],nn,mm,n,m,cnt;
char s1[N][N],s2[N][N];
unordered_map<int,int> ma;
vector<int> v;
ll ksm(ll a,ll b)
{ll ans=1;while(b){if(b&1) ans=ans*a%mod;b>>=1;a=a*a%mod;}return ans;
}
int gauss()
{int r=1,c=1;for(;r<=nn&&c<=mm;r++,c++){int maxn=r;for(int i=r+1;i<=nn;i++) if(abs(a[maxn][c])<abs(a[i][c])) maxn=i;for(int j=1;j<=mm+1;j++){swap(a[maxn][j],a[r][j]);}if(abs(a[r][c])==0){r--;continue;}for(int i=1;i<=nn;i++){if(i==r) continue;ll g=(a[i][c]*ksm((a[r][c]%mod+mod)%mod,mod-2)%mod+mod)%mod;for(int j=1;j<=mm+1;j++)a[i][j]=(a[i][j]-a[r][j]*g%mod+2*mod)%mod;}}for(int i=r;i<=nn;i++){if(abs(a[i][i])==0&&abs(a[i][mm+1])>0){return -1;}}memset(fr,0x3f,sizeof(fr));for(int i=1;i<r;i++){int cnt=0,num=0;for(int j=1;j<=mm;j++) if(fr[j]&&abs(a[i][j])>0) cnt++,num=j;if(cnt==1) fr[num]=0,val[num]=(a[i][mm+1]*ksm((a[i][num]%mod+mod)%mod,mod-2)%mod+mod)%mod;}return 1;
}
int getid(int x,int y){return (x-1)*m+y;}
void dfs(int x,int k,int state)
{if(!x){ma[state]=++cnt;v.push_back(state);return;}for(int i=0;i<=k;i++) dfs(x-1,i,state|((1<<x*m)-1^(1<<x*m-i)-1));
}
int change(int id)
{int newid=(1<<n*m)-1;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if((id>>getid(i,j)-1&1)!=(s2[i][j]=='B')){for(int ii=1;ii<=i;ii++){for(int jj=1;jj<=j;jj++){newid&=INT_MAX^(1<<getid(ii,jj)-1);}}}}}return newid;
}
int main()
{freopen("graffiti.in","r",stdin);freopen("graffiti.out","w",stdout);scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%s",s1[i]+1);for(int i=1;i<=n;i++) scanf("%s",s2[i]+1);int finish=0,start=0;for(int i=n;i>=1;i--){for(int j=m;j>=1;j--){finish=finish*2+(s2[i][j]=='B');start=start*2+(s1[i][j]=='B');}}dfs(n,m,0);int N=1<<n*m;nn=mm=v.size();for(int i=0;i<v.size();i++){int t=v[i];if(i==ma[change(finish)]-1){a[i+1][i+1]=1;continue;}int tt=0;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(t>>getid(i,j)-1&1) tt|=(s2[i][j]=='B')<<getid(i,j)-1;else tt|=(s2[i][j]=='W')<<getid(i,j)-1;}}a[ma[t]][ma[t]]+=2*n*m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){int id=tt;for(int ii=1;ii<=i;ii++){for(int jj=1;jj<=j;jj++){id|=1<<(getid(ii,jj)-1);}}int newid=change(id);a[ma[t]][nn+1]+=i*j;a[ma[t]][ma[newid]]--;for(int ii=1;ii<=i;ii++){for(int jj=1;jj<=j;jj++){id^=1<<(getid(ii,jj)-1);}}newid=change(id);a[ma[t]][nn+1]+=i*j;a[ma[t]][ma[newid]]--;}}}int czn=gauss();printf("%lld\n",val[ma[change(start)]]);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/179510.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redo Log(重做日志)的刷盘策略

1. 概述 Redo Log&#xff08;重做日志&#xff09;是 InnoDB 存储引擎中的一种关键组件&#xff0c;用于保障数据库事务的持久性和崩溃恢复。InnoDB 将事务所做的更改先记录到重做日志&#xff0c;之后再将其应用到磁盘上的数据页。 刷盘策略&#xff08;Flush Policy&#x…

如何记录每天的工作日程?电脑手机通用的日程管理软件

在工作时间有限&#xff0c;但工作任务愈加繁多的现在职场中&#xff0c;要求每一个职场人士做好高效日程管理。通过高效管理日程&#xff0c;我们可以更好地组织和安排任务&#xff0c;合理分配时间和优先级&#xff0c;这有助于我们更专注地进行工作&#xff0c;减少时间的浪…

MCU HardFault_Handler调试方法

一.获取内核寄存器的值 1.在MDK的DEBUG模式下&#xff0c;当程序出现跑飞后&#xff0c;确定卡死在HardFault_Handler中断处 2. 通过Register窗口读取LR寄存器的值来确定当前系统使用堆栈是MSP还是PSP LR寄存器值堆栈寄存器0xFFFFFFF9MSP寄存器0xFFFFFFFDPSP寄存器 如下图所…

【JavaEE】cookie和session

cookie和session cookie什么是 cookieServlet 中使用 cookie相应的API Servlet 中使用 session 相应的 API代码示例: 实现用户登陆Cookie 和 Session 的区别总结 cookie 什么是 cookie cookie的数据从哪里来? 服务器返回给浏览器的 cookie的数据长什么样? cookie 中是键值对…

HR模块开发(1):简单的开发流程和注意事项

HR模块开发 一、模块概述 人力资源管理解决方案关注3个领域:每位雇员都发展和维护着‘公司内’和‘公司外’的种种‘关系’。运用科技,强化这些关系,可以提高忠诚度和生产力,公司整体得到商业价值。 员工关系管理员工职业生命周期管理员工事务处理管理HR模块的基本知识和构…

[Unity][VR]透视开发系列4-解决只看得到Passthrough但看不到Unity对象的问题

【视频资源】 视频讲解地址请关注我的B站。 专栏后期会有一些不公开的高阶实战内容或是更细节的指导内容。 B站地址: https://www.bilibili.com/video/BV1Zg4y1w7fZ/ 我还有一些免费和收费课程在网易云课堂(大徐VR课堂): https://study.163.com/provider/480000002282025/…

算法通关村第四关-黄金挑战基础计算器问题

大家好我是苏麟 , 今天带来栈的比较难的问题 . 计算器问题 基础计算器 LeetCode 224 描述 : 给你一个字符串表达式 s &#xff0c;请你实现一个基本计算器来计算并返回它的值。 s 由数字、、-、(、)、和 组成s 表示一个有效的表达式 不能用作一元运算(例如&#xff0c; …

2014年亚太杯APMCM数学建模大赛A题无人机创造安全环境求解全过程文档及程序

2014年亚太杯APMCM数学建模大赛 A题 无人机创造安全环境 原题再现 20 国集团&#xff0c;又称 G20&#xff0c;是一个国际经济合作论坛。2016 年第 11 届 20 国集团峰会将在中国召开&#xff0c;这是继 APEC 后中国将举办的另一个大型峰会。此类大型峰会&#xff0c;举办城市…

【计算机网络】浏览器的通信能力

1. 用户代理 浏览器可以代替用户完成http请求&#xff0c;代替用户解析响应结果&#xff0c;所以我们称之为用户代理 user agent。 浏览器两大核心能力&#xff1a; 自动发送请求的能力自动解析响应的能力 1.1 自动发送请求的能力 用户在地址栏输入了一个url地址&#xff0…

[双指针] (四) LeetCode 18.四数之和

[双指针] (四) LeetCode 18.四数之和 文章目录 [双指针] (四) LeetCode 18.四数之和题目解析解题思路代码实现总结 18. 四数之和 题目解析 (1) 从一个数组中找一个目标值target (2) target nums[a] nums[b] nums[c] nums[d] 解题思路 和上一道题三数之和一样, 我们把四…

Android笔记(十一):Compose中使用ViewModel

通过ViewModel组件用于保存视图中需要的数据。ViewModel主要目的是将与用户界面相关的数据模型和应用程序的逻辑与负责实际显示和管理用户界面以及与操作系统交互的代码分离开来&#xff0c;为UI界面管理数据。常见的管理方式主要有&#xff1a;LiveData和StateFlow两种形式来实…

Redis常见风险分析

击穿 概念&#xff1a;在Redis获取某一key时, 由于key不存在, 而必须向DB发起一次请求的行为, 称为“Redis击穿”。 引发击穿的原因&#xff1a; 第一次访问恶意访问不存在的keyKey过期 合理的规避方案&#xff1a; 服务器启动时, 提前写入规范key的命名, 通过中间件拦截对…

BUUCTF FLAG 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 注意&#xff1a;请将 hctf 替换为 flag 提交&#xff0c;格式 flag{} 密文&#xff1a; 下载附件&#xff0c;得到一张.png图片。 解题思路&#xff1a; 1、因为附件是一张图片&#xff0c;先放到StegSolve中&…

CentOS 7使用RPM包安装MySQL5.7

目标 本文目标是简单介绍如何在CentOS 7上使用RPM包安装MySQL 5.7&#xff0c;然后描述如何调整存储路径datadir。 环境准备 操作系统 —— CentOS 7MySQL版本 —— MySQL 5.7.44 获取MySQL-rpm包 官网下载地址&#xff1a;https://dev.mysql.com/downloads/mysql/5.7.htm…

mysql之事务

1、事务的定义 事务是一种机制&#xff0c;一个操作序列&#xff0c;包含了一组数据库的操作命令&#xff0c;所有命令都是一个整体&#xff0c;作为一个整体向系统提交或者撤销的操作&#xff0c;要么都执行&#xff0c;要么都不执行&#xff0c;是一个不可分割的单位 2、事…

Modelsim 使用教程(3)——Projects

目录 一、概述 二、设计文件及tb 2.1 设计文件 counter.v 2.2 仿真文件 tcounter.v 三、操作流程 3.1 Create a New Project&#xff08;创建一个新的工程&#xff09; 3.2 Add Objects to the Project&#xff08;把代码加入项目&#xff09; 3.3 Compile the …

【44.全排列Ⅱ】

目录 一、题目描述二、算法原理三、代码实现 一、题目描述 二、算法原理 三、代码实现 class Solution { public:vector<vector<int>> ret;vector<int> path;vector<bool> check;vector<vector<int>> permuteUnique(vector<int>&am…

winscp文件增量同步到linux服务器

一&#xff0c;点击同步 场景&#xff1a;在做服务器迁移的时候&#xff0c;文件好几十个G一天也迁移不完&#xff0c;每天还有增量的文件&#xff0c;先全量同步一次&#xff0c;然后再用增量同步&#xff0c;然后你用winscp的同步工具&#xff0c;进增量同步。 将本地文件同…

k8s 资源预留

KUBERNETES资源管理之–资源预留 Kubernetes 的节点可以按照 Capacity 调度。node节点本身除了运行不少驱动 OS 和 Kubernetes 的系统守护进程&#xff0c;默认情况下 pod 能够使用节点全部可用容量&#xff0c; 除非为这些系统守护进程留出资源&#xff0c;否则它们将与 pod 争…

BUUCTF 另外一个世界 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 下载附件&#xff0c;解压得到一个.jpg图片。 密文&#xff1a; 解题思路&#xff1a; 1、这道题我尝试了很多方法&#xff0c;知道看了别人的wp才知道flag在我忽略的地方。将图片在010 Editor中打开&#xff0c;从…