首页 > 其他分享 >CF1592F2 Alice and Recoloring 2

CF1592F2 Alice and Recoloring 2

时间:2023-12-13 21:12:00浏览次数:28  
标签:cnt int CF1592F2 Alice st define include Recoloring dis

题意

给定一个矩阵,有两种颜色 \(W\) 和 \(B\)。

你可以花 \(1\) 的代价反转一个包含 \((1, 1)\) 的矩阵。
你可以花 \(3\) 的代价反转一个包含 \((n, 1)\) 的矩阵。
你可以花 \(4\) 的代价反转一个包含 \((1, m)\) 的矩阵。
你可以花 \(2\) 的代价反转一个包含 \((n, m)\) 的矩阵。

Sol

显然中间两种操作是消愁。直接不管。

考虑将 \(B\) 看为 \(1\),\(W\) 看为 \(0\)。

对矩阵倒着做前缀和。

\(1\) 操作变为在前缀和数组上操作一个点。

\(4\) 操作变为在前缀和数组上操作四个点。

不难发现对于同样的一列或者一行,只可能进行一次 \(4\) 操作。

注意到进行一次 \(4\) 操作当且仅当 \((x, y) = 1\),\((x, m) = 1\),\((n, y) = 1\)。

直接把每一行,每一列看成 \(n + m\) 个点。

对于第一条限制,建二分图,按照第二条限制连边跑二分图最大匹配即可。

Code

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <array>
#include <queue>
#define int long long
#define pii pair <int, int>
using namespace std;
#ifdef ONLINE_JUDGE

#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 23], *p1 = buf, *p2 = buf, ubuf[1 << 23], *u = ubuf;

#endif
int read() {
	int p = 0, flg = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') flg = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		p = p * 10 + c - '0';
		c = getchar();
	}
	return p * flg;
}
string read_() {
	string ans;
	char c = getchar();
	while (c != 'W' && c != 'B')
		c = getchar();
	while (c == 'W' || c == 'B') {
		ans += c;
		c = getchar();
	}
	return ans;
}
void write(int x) {
	if (x < 0) {
		x = -x;
		putchar('-');
	}
	if (x > 9) {
		write(x / 10);
	}
	putchar(x % 10 + '0');
}

#define fi first
#define se second

const int N = 1e3 + 5, M = 1e6 + 5, inf = 2e18;

namespace G {

array <int, N> fir;
array <int, M> nex, to, cap;
int cnt = 1;
void add(int x, int y, int z) {
	cnt++;
	nex[cnt] = fir[x];
	to[cnt] = y;
	cap[cnt] = z;
	fir[x] = cnt;
}
void _add(int x, int y, int z) {
	add(x, y, z);
	add(y, x, 0);
}

}

namespace Mfl {

array <int, N> dis, cur;
queue <int> q;

bool bfs(pii st) {
	dis.fill(-1), dis[st.fi] = 0;
	q.push(st.fi);
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		for (int i = G::fir[u]; i; i = G::nex[i]) {
			if (!G::cap[i] || ~dis[G::to[i]]) continue;
			dis[G::to[i]] = dis[u] + 1, q.push(G::to[i]);
		}
	}
	return ~dis[st.se];
}

int dfs(int x, int augcd, pii st) {
	if (x == st.se) return augcd;
	int augc = augcd;
	for (int &i = cur[x]; i; i = G::nex[i]) {
		if (!G::cap[i] || dis[G::to[i]] <= dis[x]) continue;
		int flow = dfs(G::to[i], min(augc, G::cap[i]), st);
		augc -= flow;
		G::cap[i] -= flow, G::cap[i ^ 1] += flow;
		if (!augc) break;
	}
	return augcd - augc;
}

int dinic(pii st) {
	int ans = 0;
	while (bfs(st)) {
		copy(G::fir.begin(), G::fir.end(), cur.begin());
		ans += dfs(st.fi, inf, st);
	}
	return ans;
}

}

string mp[N];

array <array <int, N>, N> s;

signed main() {
	int n = read(), m = read();
	for (int i = 1; i <= n; i++)
		mp[i] = " " + read_();
	for (int i = n; i; i--)
		for (int j = m; j; j--)
			s[i][j] = (mp[i][j] == 'B') ^
					(mp[i + 1][j] == 'B') ^
					(mp[i][j + 1] == 'B') ^
					(mp[i + 1][j + 1] == 'B');
	for (int i = 1; i < n; i++)
		for (int j = 1; j < m; j++)
			if (s[i][j] && s[i][m] && s[n][j])
				G::_add(i, j + n, 1);
	pii st = make_pair(n + m, n + m + 1);
	for (int i = 1; i < n; i++) G::_add(st.fi, i, 1);
	for (int i = 1; i < m; i++) G::_add(i + n, st.se, 1);
	int k = Mfl::dinic(st), ans = 0;
	s[n][m] ^= (k & 1);
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			ans += s[i][j];
	write(ans - k), puts("");
	return 0;
}

标签:cnt,int,CF1592F2,Alice,st,define,include,Recoloring,dis
From: https://www.cnblogs.com/cxqghzj/p/17899926.html

相关文章

  • [CF1592F2] Alice and Recoloring 2
    题目链接操作2和3可以用另两个代替,没有任何用。设W表示\(t_{i,j}=0\),B表示\(t_{i,j}=1\)考虑差分。设\(t_{i,j}=s_{i,j}\opluss_{i+1,j}\opluss_{i,j+1}\opluss_{i+1,j+1}\),那么目标变为把$t4数组清0那么操作1是把单点翻转,操作4是对于一个\(x,y(x<n,y<m)......
  • [ARC072E] Alice in linear land 题解
    [ARC072E]Aliceinlinearland首先,一个trivial的想法是记\(f_i\)表示第\(i\)步前离终点的距离,于是\(f_i=\min\Big(f_{j-1},|f_{j-1}-d_i|\Big)\)。然后,我们设\(f_i'\)表示在修改第\(i\)步后,此时离终点的距离。明显,\(f_i'\)可以为任意不大于\(f_i\)的值,因为此时......
  • Alice's Stamps
    Description给定\(n\)个区间,选择至多\(k\)个区间,使得被覆盖的元素的个数最多。求最大值。\(1\leql\leqr\leqn\)。Solution赛场上想的是用区间定义状态,先把区间按右端点排序,\(dp_{i,k}\)表示考虑前\(i\)个区间,选了其中\(k\)个,且第\(i\)个区间必选的最大值。那么就......
  • Letter Picking (CF D) (区间DP, 暴力)(0,1,2 Alice 平 bob ,尽可能小,尽可能大)
     思路:区间dp(区间DP的时间复杂度不一定是n^3,可能是n^2更具题意)直接题直接区间dp,0Alice赢1平局2Bob赢(于是alice尽可能小,bob尽可能大)alice选l,bob可以选l+1,或者ralice选r,bob可选l或者r-1,看代码就行了#include<bits/stdc......
  • Alice and Hairdresser题解
    AliceandHairdresser第一眼线段树,第二眼好像可以直接用数组模拟。当一根头发长于\(l\),它再长多长其实都一样,所以不用开longlong。如果一根新的头发长到比\(l\)长,那可以分成以下几种情况:如果它左侧和右侧只有一个元素大于\(l\),那答案不变。如果左侧和右侧都大于......
  • XTU 1209 Alice and Bob
    AliceandBob   TimeLimit:1000MS MemoryLimit:65536KB ProblemDescriptionThefamous"AliceandBob"areplayingagameagain.Sonowcomesthenewproblemwhichneedapersonsmartasyoutodecidethewinner.Theproblemisasfollows:......
  • CF1592F2 题解
    题意传送门给定一个\(n\)行\(m\)列的目标矩阵,矩阵元素只有W或B,并且你有一个初始矩阵,元素全为W。现在你可以矩阵实施以下操作:使用一块钱,选定一个包含\((1,1)\)的子矩阵,把矩阵中的元素全部反转(W变B,B变W)。使用三块钱,选定一个包含\((n,1)\)的子矩阵,把矩阵......
  • 题解【CF1592F2 Alice and Recoloring 2】
    CF1592F2AliceandRecoloring2解题报告。不一定更好的阅读体验。摘自我的构造题目选做例题IV。CF2800的构造就这?/cf/cf/cf(首先,操作2和操作3都是没有用......
  • 2022 CCPC 广州站 Alice and Her Lost Cat
    1#include<bits/stdc++.h>2usingnamespacestd;3#definergregister4#definelllonglong5#defineldlongdouble6#defineFOR(i,a,b)for(r......
  • 使用 Alice inspector 和 Dio 进行 Flutter API 日志记录
    使用Aliceinspector和Dio进行FlutterAPI日志记录前言有没有发现自己处于这样的情况下,当一个特性被显示或者一个方法被触发时,你必须找出哪个API被调用?我就当......