目前在看贪心/构造/DP 杂题选做,发现一道非常不错的结论题,具有启发意义。

先说明如下结论

结论一:如何怎么样都不会使用二和三操作

证明:

二三操作显然可以通过两次一操作达到,而其操作费用大于两次一操作费用

所以显然我们只会操作一四操作。

那么我们发现翻转一整个矩形不好操作,翻转到一特定状态也不好处理,不如考虑倒序操作:即给定特定状态变为全白状态的费用,知其与原问题等价。

然后我们处理翻转问题,我们考虑一个转换

\(a_{i,j} = a_{i,j}\ xor\ a_{i+1,j}\ xor\ a_{i,j + 1}\ xor\ a_{i + 1,j + 1}\)。

我们发现全白时显然全等为\(0\)。

而一四操作我们可以将其本质变为:

一操作:单点翻转\((x,y)\)

四操作:四点翻转\((x,y),(x,m),(n,y),(n,m)\)

那么问题变得显然起来。

我们依旧给出了两个结论

结论二:不用同时使用两个横坐标或竖坐标相等的四操作

证明:其等价于修改四个任意散点,其可以等价于四次一操作的费用

结论三:除非 \((x,y),(n,y),(x,m)\) 都为1,才会使用 \((x,y)\) 这一四操作

证明:如果有一个不为\(1\),那么其有一个错误反转,我们需要其一个一操作反转回来,那么其等价于\(1 + 2 = 3\),可以使用一操作代替。

那么经典问题转化为满足某种条件的改变行列取点数量。

二分图上最大匹配即可。

#include<iostream>
#include<cstdio>
#include<queue>
#define ll long long
#define N 30000 int n,m; int head[N]; int cnt = 1; struct P{
int to,next;
ll v;
}e[N << 2]; inline void add(int x,int y,int v){
e[++cnt].to = y;
e[cnt].v = v;
e[cnt].next = head[x];
head[x] = cnt;
} std::queue<int>QWQ;
ll dis[N];
bool vis[N]; int a[505][505]; int s,t; inline bool bfs(){
for(int i = 1;i <= n + m + 2;++i)
dis[i] = 1e10,vis[i] = 0;
dis[s] = 0;
QWQ.push(s);
vis[s] = 1;
while(!QWQ.empty()){
int u = QWQ.front();
QWQ.pop();
vis[u] = 0;
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(dis[v] > dis[u] + 1 && e[i].v){
dis[v] = dis[u] + 1;
if(!vis[v])
vis[v] = 1,QWQ.push(v);
}
}
}
return dis[t] != 1e10;
} inline ll dfs(int u,ll in){
ll out = 0;
if(u == t)
return in;
for(int i = head[u];i;i = e[i].next){
int v = e[i].to;
if(e[i].v && dis[v] == dis[u] + 1){
int to = dfs(v,std::min(e[i].v,in));
e[i].v -= to;
e[i ^ 1].v += to;
in -= to;
out += to;
}
}
if(out == 0)
dis[u] = 0;
return out;
} inline int dinic(){
int ans = 0;
while(bfs())
ans += dfs(s,1e18);
return ans;
} int main(){
scanf("%d%d",&n,&m);
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j){
char s = getchar();
while(s != 'W' && s != 'B')
s = getchar();
a[i][j] = (s == 'B');
s = '.';
}
int ans = 0;
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j){
a[i][j] = a[i][j] ^ a[i + 1][j] ^ a[i + 1][j + 1] ^ a[i][j + 1];
}
// for(int i = 1;i <= n;++i,puts(""))
// for(int j = 1;j <= m;++j)
// std::cout<<a[i][j]<<" ";
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j){
if(a[i][m] && (a[n][j] && a[i][j])){
add(i,n + j,1);
add(n + j,i,0);
}
}
s = n + m + 1,t = n + m + 2;
for(int i = 1;i < n;++i)
add(s,i,1),add(i,s,0);
for(int j = 1;j < m;++j)
add(n + j,t,1),add(t,n + j,0);
int k = dinic();
a[n][m] = a[n][m] ^ (k & 1);
for(int i = 1;i <= n;++i)
for(int j = 1;j <= m;++j)
ans += a[i][j];
std::cout<<ans - k<<std::endl;
}//注意建图后的点集大小

CF1592F2 Alice and Recoloring 2的更多相关文章

  1. 贪心/构造/DP 杂题选做

    本博客将会收录一些贪心/构造的我认为较有价值的题目,这样可以有效的避免日后碰到 P7115 或者 P7915 这样的题就束手无策进而垫底的情况/dk 某些题目虽然跟贪心关系不大,但是在 CF 上有个 ...

  2. Solution -「构造」专练

    记录全思路过程和正解分析.全思路过程很 navie,不过很下饭不是嘛.会持续更新的(应该). 「CF1521E」Nastia and a Beautiful Matrix Thought. 要把所有数 ...

  3. (HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5558 Problem Description Alice wants to send a classi ...

  4. 2016中国大学生程序设计竞赛 - 网络选拔赛 J. Alice and Bob

    Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

  5. bzoj4730: Alice和Bob又在玩游戏

    Description Alice和Bob在玩游戏.有n个节点,m条边(0<=m<=n-1),构成若干棵有根树,每棵树的根节点是该连通块内编号最 小的点.Alice和Bob轮流操作,每回合 ...

  6. Alice and Bob(2013年山东省第四届ACM大学生程序设计竞赛)

    Alice and Bob Time Limit: 1000ms   Memory limit: 65536K 题目描述 Alice and Bob like playing games very m ...

  7. 阿里前端框架Alice是个不错的选择

    BootStrap虽然用户群体广大,其整体风格尽管有不少skin可选,但以国情来看还是不好看. 阿里开源的前端框架,个人觉得还是很不错,Alice处处透着支付宝中界面风格的气息,电商感挺强. 以下内容 ...

  8. poj 1698 Alice‘s Chance

    poj 1698  Alice's Chance 题目地址: http://poj.org/problem?id=1698 题意: 演员Alice ,面对n场电影,每场电影拍摄持续w周,每周特定几天拍 ...

  9. Alice and Bob 要用到辗转相减

    Alice and BobTime Limit: 1 Sec  Memory Limit: 64 MBSubmit: 255  Solved: 43 Description Alice is a be ...

随机推荐

  1. 【.Net vs Java? 】 看一看二者的类有多像?

    1. 包(Package).命名空间(NameSpace) 1.1 概念 在Java中常用的是包(Package),较少提到NameSpace的概念.Java官方文档中这样说: 为了使类型更易于查找和 ...

  2. NXOpen.CAM.CAMSetup.CopyObjects的使用

    复制CAM对象 Public Function CopyObjects(ByVal view As NXOpen.CAM.CAMSetup.View, ByVal objectsToBeMoved() ...

  3. Hive面试题整理(一)

    1.Hive表关联查询,如何解决数据倾斜的问题?(☆☆☆☆☆)   1)倾斜原因:map输出数据按key Hash的分配到reduce中,由于key分布不均匀.业务数据本身的特.建表时考虑不周.等原因 ...

  4. Servlet学习一(Servlet的使用流程)

    一.servlet运行流程 运行流程:浏览器发送请求到服务器,服务器根据url地址在webapps中寻找对应的项目文件夹然后再web.xml中检索对应的servlet,并进行调用二.servlet类写 ...

  5. 你知道怎么从jar包里获取一个文件的内容吗

    目录 背景 报错的代码 原先的写法 编写测试类 找原因 最终代码 背景 项目里需要获取一个excle文件,然后对其里的内容进行修改,这个文件在jar包里,怎么尝试都读取不成功,但是觉得肯定可以做到,因 ...

  6. 用Python去除PDF水印

    今天介绍下用 Python 去除 PDF (图片)的水印.思路很简单,代码也很简洁. 首先来考虑 Python 如何去除图片的水印,然后再将思路复用到 PDF 上面. 这张图片是前几天整理<数据 ...

  7. 从零开始 DIY 智能家居 - 基于 ESP32 的智能语音合成播报模块

    目录 前言 硬件选择 代码解析 获取代码 设备控制命令: 设备和协议初始化流程: 配置设备信息 回调函数注册 语音播报与设置流程 总结 前言 这里这么多设备,突然发现我做的好像都是传感器之类的居多好像 ...

  8. hdu 4288 Coder(单点操作,查询)

    题意: 三种操作: 1. add x – add the element x to the set;2. del x – remove the element x from the set;3. su ...

  9. 创建双向 CA x509 验证证书 kube-apiserver

    1. 设置 kube-apiserver 的 CA 证书相关的文件和启动参数 使用 OpenSSL 工具在 Master 服务器上创建 CA 证书和私钥相关的文件: # openssl genrsa ...

  10. 更优于 Shellinabox 的 web shell 工具 -- ttyd

    ttyd 是一个运行在服务端,客户端通过web浏览器访问从而连接后台 tty (pts伪终端)接口的程序,把 shell 终端搬到 web 浏览器中. WebSocket WebSocket 是 HT ...