2023NOIP A层联测23 T2 涂鸦

模拟赛一道博弈,剩下仨全期望,我:

思路

其实我也不是很会

考虑设 \(f_{mst}\),为 \(n*m\) 个格被压成一个二进制 \(mst\),转移到最终状态的期望花费。

可以列出方程

\[f_{mst}=\frac{\sum f_j + w}{2nm}
\]

\(j\) 为 \(mst\) 通过一次变换可以到达的状态,\(w\) 为到这个状态的花费。

若 \(j\) 为最终状态,则 \(f_j=0\)。

可以暴力的高斯消元解方程组,时间复杂度 \(2^{3nm}\)。

后面的优化变得科学(玄学)起来。

如果某个状态 \(i\) 行 \(j\) 列与目标状态不同,那么在这个位置,一定要进行一次覆盖 \((1,1)\) 到 \((i,j)\) 的操作。

把所有的覆盖操作提取出来,发现覆盖的范围够成了一个阶梯形。

如图:

图中蓝色部分为一次覆盖操作,红色部分为与目标状态相同的部分。

这些覆盖操作有效的只有红蓝交界的覆盖。

why?

红蓝交界的覆盖表示了某个状态与目标状态红色状态相同,蓝色状态不同。而在蓝色部分内的覆盖如果执行了,那么相同部分会增加,也就是变成了别的红蓝状态。

我们可以发现,组成相同红蓝状态的原状态到目标状态的值是一样的。(因为都需要覆盖最外层,即交界的蓝色部分)

而红蓝状态的状态数较少,这样我们就缩小了状态数。

方程可以这么列:

1.得出红蓝状态,可以用二进制表示。

2.某个红蓝状态转回原状态。(任意转成一个即可,方便起见,红色部分与目标相同,蓝色部分与目标完全相反)

3.通过原状态暴力枚举操作,转移到其他的红蓝状态,列出方程。(方程类似于优化前的,相当于把原状态的未知数全部换成对于的红蓝状态的未知数。也就是说,一个红蓝状态对于多个原状态的未知数)

列出方程以后就可以愉快的高斯消元了。

CODE

#include<bits/stdc++.h>
using namespace std; #define ll long long const ll mod=998244353;
const int maxn=260; int n,m,cnt,beg,fin,nn; bool f[maxn]; ll a[maxn][maxn],val[maxn]; char st[10][10],ed[10][10]; unordered_map<int,int>mp; vector<int>v; ll ksm(ll x,ll y)
{
int sum=1;
for(;y;y/=2,x=x*x%mod) if(y&1) sum=sum*x%mod;
return sum;
}
int gtid(int x,int y){return (x-1)*m+y;} void dfs(int x,int k,int state)
{
if(!x)
{
mp[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>>gtid(i,j)-1&1)!=(ed[i][j]=='B'))
{
for(int ii=1;ii<=i;ii++)
{
for(int jj=1;jj<=j;jj++) newid&=INT_MAX^(1<<gtid(ii,jj)-1);
}
}
}
}
return newid;
} void gsxy()
{
int r=1,c=1;
for(;r<=nn&&c<=nn;r++,c++)
{
int mxid=r;
for(int i=r+1;i<=nn;i++) if(abs(a[mxid][c])<abs(a[i][c])) mxid=i;
for(int i=1;i<=nn+1;i++) swap(a[mxid][i],a[r][i]);
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<=nn+1;j++) a[i][j]=(a[i][j]-a[r][j]*g%mod+mod)%mod;
}
}
memset(f,1,sizeof(f));
for(int i=1;i<=nn+1;i++)
{
int ct=0,id=0;
for(int j=1;j<=nn;j++) if(f[j]&&abs(a[i][j])) ct++,id=j;
if(ct==1) f[id]=0,val[id]=(a[i][nn+1]*ksm(a[i][id]%mod+mod,mod-2)%mod+mod)%mod;
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",st[i]+1);
for(int i=1;i<=n;i++) scanf("%s",ed[i]+1);
dfs(n,m,0);
for(int i=n;i;i--)
{
for(int j=m;j;j--)
{
fin=fin*2+(ed[i][j]=='B');
beg=beg*2+(st[i][j]=='B');
}
}
nn=v.size();
for(int i=0;i<v.size();i++)
{
int t=v[i];
if(i==mp[change(fin)]-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>>(gtid(i,j)-1)&1) tt|=(ed[i][j]=='B')<<(gtid(i,j)-1);
else tt|=(ed[i][j]=='W')<<gtid(i,j)-1;
}
}
a[mp[t]][mp[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<<(gtid(ii,jj)-1);
}
}
a[mp[t]][nn+1]+=i*j;
a[mp[t]][mp[change(id)]]--;
for(int ii=1;ii<=i;ii++)
{
for(int jj=1;jj<=j;jj++)
{
id^=1<<(gtid(ii,jj)-1);
}
}
a[mp[t]][nn+1]+=i*j;
a[mp[t]][mp[change(id)]]--;
}
}
}
gsxy();
printf("%lld\n",val[mp[change(beg)]]);
}

懒得加注释了,思路很清晰,位运算可以自己琢磨一下更改了那些格子。

2023NOIP A层联测23 T2 涂鸦的更多相关文章

  1. Wannafly挑战赛23 T2游戏 SG函数

    哎,被卡科技了,想了三个小时,最后还是大佬给我说是\(SG\)函数. \(SG\)函数,用起来很简单,证明呢?(不可能的,这辈子都是不可能的) \(SG\)定理 游戏的\(SG\)函数就是各个子游戏的 ...

  2. k3 Bos开发百问百答

              K/3 BOS开发百问百答   (版本:V1.1)           K3产品市场部       目录 一.基础资料篇__ 1 [摘要]bos基础资料的显示问题_ 1 [摘要]单 ...

  3. 使用ajax实现无刷新改变页面内容

    如何使用ajax实现无刷新改变页面内容(也就是ajax异步请求刷新页面),下面通过一个小demo说明一下,前端页面代码如下所示 1 <%@ Page Language="C#" ...

  4. 如何对于几百行SQL语句进行优化?

    1.最近在开发中遇到的一些关于几百行SQL语句做查询的问题,需要如何的解决优化SQL这确实是个问题,对于当下的ORM 框架 EF 以及其他的一些的开源的框架例如Drapper ,以及Sqlite-Su ...

  5. java ---线程wait/notify/sleep/yield/join

    一.线程的状态 Java中线程中状态可分为五种:New(新建状态),Runnable(就绪状态),Running(运行状态),Blocked(阻塞状态),Dead(死亡状态). New:新建状态,当线 ...

  6. 重新开始学习javase_IO

    一,认识IO 通过数据流.序列化和文件系统提供系统输入和输出. 流是一个很形象的概念,当程序需要读取数据的时候,就会开启一个通向数据源的流,这个数据源可以是文件,内存,或是网络连接.类似的,当程序需要 ...

  7. Python学习--17 访问数据库

    实际开发中,我们会经常用到数据库. Python里对数据库的操作API都很统一. SQLite SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以 ...

  8. [补档]暑假集训D4总结

    考试 爆零了,不开心,打了两道自己以为是正解的东西,打了两道样例骗分,结果发现并没有给样例分= =,自己以为的正解也打挂了,所以就很= = 但是没办法啊,自己弱也不能怪谁,考试这东西有时候也很玄学. ...

  9. YOLO 从数据集制作到训练

    1.图片数据集收集 共 16种 集装箱船 container ship 散货船 bulker 油船 tanker 游轮 / 客轮 / 邮轮 passenger liner 渔船 fishing boa ...

  10. [原][osg][oe]分析一块倾斜摄影瓦片的数据

    RangeMode PIXEL_SIZE_ON_SCREEN 首先我们看看原始数据的构成: 第12层:(第一层) 第23层:(最后一层) pagelod下面有N多的pagelod一层包裹一层 通过os ...

随机推荐

  1. 记一次list集合优化

    已知某个列表List1有2000条数据,但是因为这个列表的某个字段要从另一个表查询,所以根据一个关联的查询条件查出来的另一个List2有将近75000条数据,然后需要先循环第一个List1,然后循环里 ...

  2. freertos学习笔记(十一)直接任务通知

    直接任务通知 起源 队列和信号量是实时操作系统的典型功能,而FreeRTOS提供的直接任务通知比队列和信号量更小且速度更快(快45%) 开发人员应优先使用量身定制的功能:直接任务通知.消息缓冲区和流缓 ...

  3. 【爬虫实战】——利用bs4和正则表达式,简单实现爬取数据

    前言 好久没有写博客了,由于一直比较忙,感觉快荒废了学习的步伐,最近由于需要利用爬虫爬取数据,总结一下,以便以后查阅. 目录 一.bs4的安装 二.bs4解析器 三.定位查找标签 四.转换格式 五.提 ...

  4. 反转字符串II(541)

    题目描述 给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符. 如果剩余字符少于 k 个,则将剩余字符全部反转. 如果剩余字符小于 2 ...

  5. 出海浪头之上,共探CDN进化新支力

    CDN技术自问世以来已超过20个年头,在云计算与AI深度融合的大趋势下,各行业实际业务需求已发生巨变,下一代CDN技术又将走向何方?8月16日,"抓住泛娱热趋,打通增长脉络--大浪淘沙之后的 ...

  6. 图解Zabbix设置邮件报警

    Zabbix设置邮件告警   前提条件: Zabbix Server 和 Zabbix Agent都已安装完毕,并已启动   1.添加主机   2.配置邮件告警,这里以VSFTP服务为例 yum in ...

  7. Dockerfile介绍及常用保留指令

    从本文开始,咱们将介绍docker的另外一个技术点:dockerfile.我们来看看DockerFile相关的知识点,我们将怎么学习? 1:DockerFile是什么? 2:DockerFile构建过 ...

  8. 关于安装李沐深度学习d2l包报错的解决办法(保姆教程)

    目录 目录:d2l包安装失败的解决过程 前言 一.李沐提供的安装方式 1. 创建一个新的环境 2. 激活 d2l 环境 3. 安装深度学习框架和d2l软件包 3.1 安装PyTorch的CPU或GPU ...

  9. 各种好用的免费快递物流API 接口分享

    全国快递物流查询:1.提供包括申通.顺丰.圆通.韵达.中通.汇通等 600+快递公司在内的快递物流单号查询.2.与官网实时同步更新.3.自动识别快递公司. 全国快递物流地图轨迹查询:[H5 物流轨迹. ...

  10. 游戏AI行为决策——MLP(多层感知机/人工神经网络)

    游戏AI行为决策(特别篇)--MLP(附代码与项目) 你一定听说过神经网络的大名,你有想过将它用于游戏AI的行为决策上吗?其实在(2010年发布的)<最高指挥官2>中就有应用了,今天请允许 ...