目前在看贪心/构造/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. Java(35)IO特殊操作流&Properties集合

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228454.html 博客主页:https://www.cnblogs.com/testero ...

  2. Java并行任务框架Fork/Join

    Fork/Join是什么? Fork意思是分叉,Join为合并.Fork/Join是一个将任务分割并行运行,然后将最终结果合并成为大任务的结果的框架,父任务可以分割成若干个子任务,子任务可以继续分割, ...

  3. 微服务网关Ocelot加入IdentityServer4鉴权-.NetCore(.NET5)中使用

    Consul+Ocelot+Polly在.NetCore中使用(.NET5)-Consul服务注册,服务发现 Consul+Ocelot+Polly在.NetCore中使用(.NET5)-网关Ocel ...

  4. pycharm安装第三方库

    https://jingyan.baidu.com/article/4853e1e54b845e1909f7268f.html

  5. [no code] Scrum Meeting 博客目录

    项目 内容 2020春季计算机学院软件工程(罗杰 任健) 2020春季计算机学院软件工程(罗杰 任健) 作业要求 Scrum Meeting博客目录 我们在这个课程的目标是 远程协同工作,采用最新技术 ...

  6. [no code][scrum meeting] Alpha 7

    项目 内容 会议时间 2020-04-13 会议主题 OCR技术细节分析 会议时长 30min 参会人员 PM+OCR组成员 $( "#cnblogs_post_body" ).c ...

  7. Makefile目标文件搜索(VPATH和vpath

    转载:http://c.biancheng.net/view/7051.html 我们都知道一个工程文件中的源文件有很多,并且存放的位置可能不相同(工程中的文件会被放到不同的目录下),所以按照之前的方 ...

  8. 『学了就忘』Linux基础 — 17、远程服务器关机及重启时的注意事项

    目录 1.为什么远程服务器不能关机 2.远程服务器重启时需要注意两点 3.不要在服务器访问高峰运行高负载命令 4.远程配置防火墙时不要把自己踢出服务器 5.指定合理的密码规范并定期更新 6.合理分配权 ...

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

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

  10. python解释器下载安装指导

    一.python解释器下载 想要通关python这项语言与计算机进行沟通,我们就必须下载一款能让计算机理解python这项语言的解释器,这时候我们就需要到网上下一个python解释器. python解 ...