CF1592F2 解题报告
elbissoPtImaerD · · 题解
管理辛苦了!
反复发现性质,然后逐步转化的普通题,但是我为什么不会???
一个很容易看到的事情是,
那么我们只需要考虑
将前者记为操作一,后者为操作二。
使用操作题的常规考虑手段:考察每次操作中的不变量。
如果让输入的字符串记为
那么操作一相当于使一个
目标便是让
贪心地,考虑充分利用操作二。
但是还不能直接贪心。
考虑如果对
每一列同理。
所以我们得出一个结论:对每行/列至多执行一次操作二。
这里已经隐隐有点最大匹配的影子了。
但是还没结束。
我们发现:如果
所以操作二执行的另一必要条件是
所以只需要对符合上述条件的点对
最后记得处理
细节看代码:
const int N=503,NN=N<<1;
int n,m,mc[NN],vis[NN],res,ans;
bool a[N][N];
sd vector<int>G[NN];
bool dfs(int u,int tg)
{
if(vis[u]==tg) return false;
vis[u]=tg;
for(int v:G[u]) if(!mc[v]||dfs(mc[v],tg)) return mc[v]=u,true;
return false;
}
void Solve()
{
rd(n,m);
for(int i=1;i<=n;++i)
{
char s[N];
rd(s);
for(int j=0;j<m;++j) a[i][j+1]=s[j]=='B';
}
for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) a[i][j]^=a[i+1][j]^a[i][j+1]^a[i+1][j+1],ans+=a[i][j];
for(int i=1;i<n;++i) for(int j=1;j<m;++j) if(a[i][j]&&a[i][m]&&a[n][j]) G[i].push_back(j+n);
for(int i=1;i<=n;++i) res+=dfs(i,i);
ans-=a[n][m],wrt(ans-res+(a[n][m]^res&1));
return;
}