BITACM 2026 寒假集训 A组 题解

BITACM 2026 寒假集训 A组 题解

[2026-01-19] 2024 National Invitational of CCPC (Zhengzhou)

Problem L. Toxel 与 PCPC II

You are given an strictly increasing sequence \(\vec{a}=(a_i)_{i=1}^n\in(\mathbb{N}\cap[1,mx])^n\ (n,mx\in\mathbb{N}^*)\). Find

\[\min_{\vec{p}=(p_i)_{i=0}^m,\ m\in\mathbb{N}^*,\ p_0=0,\ p_m=a_n}\sum_{i=1}^m\left(a_{p_i}+(p_i-p_{i-1})^4\right). \]

It is guaranteed that \(n,mx\leq2\times10^5\).

我感觉这做法挺神秘的,我没想到居然这么多人轻松写出来了。

DP的思路是很显然的,关键是如何优化。设\(f_i\)为在前\(i\)个元素中插入若干\(p\)的节点能得到的最小值,于是

\[f_i=\min\{a_i+i^4,\min_{j=1}^{i-1}\left(f_j+a_i+(i-j)^4\right)\}\ (i\in\mathbb{N}^*,\ i\leq n). \]

这个时间复杂度是\(\varTheta(n^2)\)的,无论怎样卡常,极限数据在我的电脑上都需要\(7.8\ \mathrm{s}\)左右,所以必须考虑优化。外层循环恐怕难以避免,因此考虑优化里面的那个\(\min\)

考虑固定的一段\(a_1,\dots,a_i\),这也是DP中我们每次考虑的子问题。如果不分段,则总代价就是\(a_i+i^4\);如果插入一个节点\(j\)而将其分为\(a_1,\dots,a_j\)\(a_{j+1},\dots,a_i\)两段,则总代价变为\((a_j+j^4)+(a_i+(i-j)^4)=(a_j+a_i)+(j^4+(i-j)^4)\),也就是增加和的第一部分部分而减少第二部分(下标差的四次方)。坐标差的最大值的数量级与第一部分的数量级是相同的(\(2\times10^5\)),而第二部分是坐标差的四次方,因此第二部分增加的速度远比第一部分快,在一定范围内我们会尽量增加节点个数以使第二部分尽量小。关键就是这个“一定范围”到底是个甚么范围。

\(\delta=i-j\)。当\(j\)\(j\)变化到\(j+1\)时,\(\delta\)\(\delta\)变化到\(\delta-1\),第二部分的减小量

\[\varDelta=\delta^4-(\delta-1)^4=4\delta^3-6\delta^2+4\delta-1=4\delta^3\left(1-\frac{6}{\delta}+\frac{4}{\delta^2}-\frac{1}{\delta^3}\right). \]

如果\(\varDelta\)足够大,也就是\(\varDelta>mx\),那末第二部分的减少量是第一部分无论如何增加都无法比拟的,也就是说,此时插节点一定比不插好。因为

\[\varDelta\to4\delta^3\ (\delta\to+\infty), \]

所以可以用

\[4\delta^3>mx \]

来估算\(\varDelta>mx\)。解得\(\delta>\sqrt[3]{\frac{1}{4}mx}\leq\sqrt[3]{2\times10^5/4}\approx37\),这个数字是很小的。不过我们上面用了估算,保险起见应当多取一点,反正时间很充裕。我取的\(64\),这个值绰绰有余。不过要注意:设初值的时候(第12行)计算四次方是有溢出的可能的(\((2\times10^5)^4=1.6\times10^{21}\)),所以要注意特殊处理一下。

inline uint64_t sq(uint64_t x) { return (x * x); }

inline void solve() {
	constexpr size_t D = 64; // cbrt(2e5 / 4) ~= 37
	size_t n;
	std::cin >> n >> n; // overwrite mx because we do not need it
	std::vector<uint64_t> arr(n);
	for (auto &e : arr) std::cin >> e;
	std::vector<uint64_t> dp(n);
	for (size_t i = 0; i < n; ++i) {
		size_t beg = ((i >= D) ? (i - D) : 0);
		dp[i] = (beg ? UINT64_MAX : arr[i] + sq(sq(i + 1)));
		// for (size_t j = 0; j < i; ++j) {
		// 	dp[i] = std::min(dp[i], dp[j] + arr[i] + sq(sq(i - j)));
		// }
		for (size_t j = ((i >= D) ? (i - D) : 0); j < i; ++j) {
			dp[i] = std::min(dp[i], dp[j] + arr[i] + sq(sq(i - j)));
		}
	}
	std::cout << dp[n - 1] << '\n';
}

时间复杂度:\(\varTheta(n\sqrt[3]{mx})\)
空间复杂度:\(\varTheta(1)\)额外空间。

Educational Codeforces Round 157

C. Torn Lucky Ticket

A ticket is a non-empty string of digits from \(1\) to \(9\).

A lucky ticket is such a ticket that:

  • it has an even length;
  • the sum of digits in the first half is equal to the sum of digits in the second half.

You are given \(n\) ticket pieces \(s_1,\dots,s_n\). How many pairs \((i,j)\) (for \(1\leq i,j\leq n\leq2\times10^5\)) are there such that \(s_is_j\) is a lucky ticket? Note that it's possible that \(i=j\). Here, \(s_is_j\) denotes the concatenation of the two strings.

It is guaranteed that \(\forall i\in\mathbb{N}\cap[1,n]\ (1\leq|s_i|\leq5)\).

朴素做法是直接枚举要拼接的两个字符串,然后按照规则验证是否lucky,时间复杂度为\(\varTheta(5\cdot n^2)\)。考虑优化掉内层循环,也就是只枚举一个字符串。因为我们只关心前后两半的和是否相等,如果知道拼接的两字符串中较长的那一个、较短的那一个的长度和二者的前后关系(拼接时谁是前缀谁是后缀),则较短的那一个的数位之和也能确定出来,进而前后两半的数位和也能分别计算了。于是我们就只需外层枚举较长的字符串,内层枚举较短字符串的长度(注意要与较长字符串的长度的同奇偶)。可以预处理出每个长度各种数位和的字符串有多少个,这样这里就可以\(\varTheta(1)\)查询。注意特别处理两字符串长度相等的情况,避免重复计算。

inline void solve() {
	constexpr size_t L = 5;
	size_t n;
	std::cin >> n;
	std::vector<std::string> strs(n);
	std::array<std::array<uint32_t, 9 * L + 1>, L + 1> cnt{};
	for (size_t i = 0; i < n; ++i) {
		std::cin >> strs[i];
		uint32_t sum = 0;
		for (char ch : strs[i]) sum += (ch ^ '0');
		++cnt[strs[i].size()][sum];
	}
	size_t res = 0;
	for (const auto &longer_str : strs) {
		size_t longer_len = longer_str.size();
		for (size_t shorter_len = (longer_len & 1); shorter_len <= longer_len; shorter_len += 2) {
			auto half_len = shorter_len + ((longer_len - shorter_len) >> 1);
			uint32_t tot_sum = 0;
			for (char ch : longer_str) tot_sum += (ch ^ '0');

			// 1. the longer one play as the prefix
			uint32_t pref_half_sum = 0;
			for (size_t i = 0; i < half_len; ++i) pref_half_sum += (longer_str[i] ^ '0');
			if ((pref_half_sum << 1) >= tot_sum) {
				res += cnt[shorter_len][(pref_half_sum << 1) - tot_sum];
			}

			if (longer_len == shorter_len) continue; // avoid double counting

			// 2. the longer one play as the suffix
			uint32_t suff_half_sum = 0;
			for (size_t i = 0; i < half_len; ++i) suff_half_sum += (longer_str[longer_len - 1 - i] ^ '0');
			if ((suff_half_sum << 1) >= tot_sum) {
				res += cnt[shorter_len][(suff_half_sum << 1) - tot_sum];
			}
		}
	}
	std::cout << res << '\n';
}

时间复杂度:\(\varTheta(5\cdot n)\)
空间复杂度:\(\varTheta((5+1)\cdot(9\times5+1))\)

D. XOR Construction

You are given \(n\leq2\times10^5\) integers \(\vec{a}=(a_i)_{i=0}^{n-1}\), and need to construct an array \(\vec{b}=(b_i)_{i=0}^n\) which is a permutation of \(\mathbb{N}\cap[0,n]\), such that

\[\forall i\in\mathbb{N}\cap[0,n)\ (b_i\oplus b_{i+1}=a_i). \]

It is guaranteed that it's always possible to construct at least one valid \(\vec{b}\). If there are multiple such arrays, you may print any of them.

这是个定义在异或运算上的“等差数列”。因此可以写出\(\vec{b}\)的通项公式

\[\forall i\in\mathbb{N}\cap[0,n)\ \left(b_{i+1}=b_i\oplus\bigoplus_{j=0}^ia_j\right). \]

显然可以先用前缀和优化掉里面那一坨。设\(\vec{s}=(s_i)_{i=0}^{n-1}=\left(\bigoplus_{j=0}^i\right)_{i=0}^{n-1}\),则

\[\forall i\in\mathbb{N}\cap[0,n)\ (b_{i+1}=b_i\oplus s_i). \]

但是由于\(b_0\)不确定,我们的\(\vec{b}\)现在尚有\(n\)种可能,我们需要选出其中满足

\[\forall i\in\mathbb{N}\cap[0,n]\ (b_i\leq n) \]

的一组。之所以不需要考虑重复的问题,是因为假如有\(i,j\in\mathbb{N}\cap[0,n]\)满足\(b_i=b_j\),则由异或的消去律得\(s_i=s_j\),此时无论\(b_0\)如何取都无法使\(b_0\oplus s_i\neq b_0\oplus s_j\),但题目告诉我们保证存在满足条件的\(\vec{b}\),因此肯定不会有重复的情况发生,只要保证在范围内就行了。

进一步地,我们其实是要确定\(b_0\)使得

\[\max_{i=0}^nb_i=\max_{i=0}^nb_0\oplus s_i\leq n. \]

于是回归到了经典问题:一个常量异或一个数组的最大值如何求呢?答案就是字典树。于是问题就解决了。

[2026-01-21] 2023 Jiangsu Collegiate Programming Contest

F. Timaeus

Timaeus can create exactly one product by combining \(n\in\mathbb{N}^*\) materials in a single synthesis. In each synthesis, he can choose one person from Sato and Mona to ask for help. With help from Sato, he has a possibility \(p\) of producing twice the output, i.e. producing two product by combining \(n\) materials in a single synthesis; with help from Mona, he has a possibility \(q\) of retrieving one material, i.e. producing one product and simultaneously recover one material by combining \(n\) materials in a single synthesis. Now he has \(m\in\mathbb{N}^*\) materials in total. Find out the maximum expected number of products he can produce.

It is guaranteed that \(n\leq m\leq10^6\) and \(p,q\in\{\varpi\%:\varpi\in\mathbb{N},\ \varpi<100\}\).

莫娜的这个返还原材料很吓人。我一开始不是没考虑DP,但想的是按莫娜合成的次数来转移,这样就想不出来了。

\(f_i\ (i\in\mathbb{N},\ i\leq m)\)表示用\(i\)个原材料能合成的产品数的最大期望。于是状态转移方程就很显然了:

\[\begin{aligned} f_i&=\max\{p\cdot(f_{i-n}+2)+(1-p)\cdot(f_{i-n}+1),q\cdot(f_{i-n+1}+1)+(1-q)\cdot(f_{i-n}+1)\}\\ &=\max\{f_{i-n}+p,q\cdot f_{i-n+1}+(1-q)\cdot f_{i-n}\}+1 & (i\in\mathbb{N},\ i\geq n). \end{aligned} \]

递推边界为

\[\forall i\in\mathbb{N}\cap[0,n)\ (f_i=0). \]

不过\(n=1\)需要特殊处理,否则会出现\(f_i\)依赖\(f_i\)的循环依赖情况,因为莫娜有可能无限地产出而不消耗材料。但由于莫娜要么正常消耗\(n=1\)个材料,要么不消耗材料,她不会对其他材料产生任何影响,因此我们可以独立地看待每一份材料,要么给莫娜,要么给砂糖。于是只需比较对一份材料,两人产出的期望即可。砂糖的额外产量服从参数为\(p\)的0-1分布,因此总产量期望为\((p+1)\)。莫娜产出\(x\in\mathbb{N}^*\)个产品的概率为\(q^{x-1}(1-q)\),因此其期望为

\[\begin{aligned} \sum_{x=1}^{+\infty}q^{x-1}(1-q)\cdot x&=\frac{1-q}{q}\sum_{x=1}^{+\infty}q^xx\\ &=\frac{1-q}{q}\sum_{x=1}^{+\infty}\frac{1}{q-1}\left(q^{x+1}\left((x+1)-\frac{q}{q-1}\right)-q^x\left(x-\frac{q}{q-1}\right)\right)\\ &=\frac{1}{q}\left(q^1\left(1-\frac{q}{q-1}\right)-\lim_{x\to+\infty}q^{x+1}\left((x+1)-\frac{q}{q-1}\right)\right)\\ &=\frac{1}{q}\left(\frac{q}{1-q}-0\right)\\ &=\frac{1}{1-q}. \end{aligned} \]

因此只要选择两人中期望较大的,把所有材料都给她就行。

inline void solve() {
	uint32_t m, n, p, q;
	std::cin >> m >> n >> p >> q;
	std::cout << std::setprecision(15) << std::fixed;
	if (n == 1) {
		std::cout << (m * std::max((p / 100.0 + 1), 100 / (100.0 - q))) << std::endl;
		return;
	}
	std::vector<double> dp(m + 1);
	for (uint32_t i = n; i <= m; ++i) {
		dp[i] = std::max(dp[i - n] + p / 100.0, q / 100.0 * dp[i - n + 1] + (1 - q / 100.0) * dp[i - n]) + 1;
	}
	std::cout << dp[m] << std::endl;
}

时间复杂度:\(\varTheta(m-n)\)
空间复杂度:\(O(m)\)

E. LCM Plus GCD

You are give two integers \(n,s\). Your task is to determine the total number of sets \(S\subseteq\mathbb{N}^*\) such that \(|S|=n\) and

\[\gcd_{x\in S}x+\operatorname*{lcm}_{x\in S}x=s. \]

It is guaranteed that \(n,s\leq10^9\). As the result could potentially be a very large number, you should provide the output modulo \(10^9+7\).

[2026-01-23] 2024 ICPC National Invitational Collegiate Programming Contest (Wuhan Site)

K. Party Games

There is a sequence of \(n\in\mathbb{N}^*\) integers \(1,\dots,n\). Alice and Bob take turns to play a game. In each turn, if the bitwise xor sum of the sequence is not \(0\), the current player removes either the first or last integer from the sequence without changing the order of the remaining integers; otherwise the current player loses the game. Obviously, for any given \(n\), the game ends after no more than \(n\) turns, so there are no draws.

Alice always goes first, and both the players aim for victory by making optimal moves. Determine who will win the game.

There are \(T\in\mathbb{N}\cap[1,10^5]\) rounds of games. For any round, it is guaranteed that \(n\leq10^6\).

比赛时打印出来找规律发现了,但是我们这里严谨推导一下这个有意思的结论,即自然数的异或和通项公式。

因为对于任意\(m\in\mathbb{N}\),有

\[(2m)\oplus(2m+1)=1, \]

所以必有

\[\bigoplus_{i=0}^3(4m+i)=1\oplus1=0, \]

于是

\[\begin{cases} \bigoplus_{i=0}^{4m}i=0\oplus4m=4m \\ \bigoplus_{i=0}^{4m+1}=4m\oplus(4m+1)=1 \\ \bigoplus_{i=0}^{4m+2}=1\oplus(4m+2)=4m+3\\ \bigoplus_{i=0}^{4m+3}=(4m+3)\oplus(4m+3)=0 \end{cases}, \]

\[\bigoplus_{i=0}^ni= \begin{cases} n & (n\bmod4=0) \\ 1 & (n\bmod4=1) \\ n+1 & (n\bmod4=2) \\ 0 & (n\bmod4=3) \end{cases}. \]

有了以上结论,这道题就很简单了。根据\(n\bmod4\)的值分类讨论:

  1. 此时Alice可以删掉\(n\),剩下的数的异或和为\(0\),Alice必胜。

  2. Alice显然不能删\(n\),否则就会把\((n-1)\equiv0\pmod{4}\)的必胜局面留给Bob,她只能删\(1\)。删\(1\)后,由于

    \[\bigoplus_{i=2}^ni=1\oplus\bigoplus_{i=1}^ni=1\oplus 1=0 \]

    即剩下的数异或和为\(0\),所以Alice必胜。

  3. Alice显然不能删\(n\),否则就会把\((n-1)\equiv1\pmod{4}\)的必胜局面留给Bob,她只能删\(1\)。删\(1\)后,由于

    \[\bigoplus_{i=2}^{n-1}i=1\oplus n\oplus\bigoplus_{i=1}^ni=1\oplus n\oplus(n+1)=1\oplus1=0, \]

    所以Bob只需删\(n\)即可获胜,即Alice必输。

  4. Alice上来就输了,输得很彻底。

inline void solve() {
	constexpr char LOSE[] = "Pinkie Pie", WIN[] = "Fluttershy";
	uint32_t n;
	std::cin >> n;
	if (!n) {
		std::cout << LOSE << '\n';
		return;
	}
	if (!(n & 0b11 & 0b10)) {
		std::cout << WIN << '\n';
	} else {
		std::cout << LOSE << '\n';
	}
}

F. Custom-Made Clothes

This is an interactive problem.

There is an \(n\times n\) matrix \(a=((a_{i,j})_{j=1}^n)_{i=1}^n\in(\mathbb{N}\cap[1,n^2])^2\) satisfying that

\[(\forall i\in\mathbb{N}\cap[1.n))\ (\forall j\in\mathbb{N}\cap[1.n])\ (a_{i,j}\leq a_{i+1,j}) \]

and

\[(\forall i\in\mathbb{N}\cap[1.n])\ (\forall j\in\mathbb{N}\cap[1.n))\ (a_{i,j}\leq a_{i,j+1}), \]

i.e. each row and each column of \(a\) is monotonically increasing, respectively.

You're provided with only the size \(n\in\mathbb{N}^*\) of the matrix, without knowledge of its element values. However, you can inquire for no more than \(5\times10^4\) times whether a given position \(a_{i,j}\) in the matrix is not greater than a specified integer \(x\), where \(i,j,x\) are determined by you.

You need to find the \(rk\)-th (\(rk\in\mathbb{N}^*,\ rk\leq n^2\)) largest element in \(a\) using the limited queries. Here, The \(rk\)-th largest value is defined as the value of the \(rk\)-th element when sorting the \(n^2\) elements in descending order.

Note that there may be identical values in \(a\).

It is guaranteed that \(n\leq1000\), and the matrix remains unchanged during the interaction.

因为矩阵元素都从\(\mathbb{N}\cap[1,n^2]\)中取出,所以可以考虑二分答案。定义\(f:x\mapsto\sum_{i=1}^n\sum_{j=1}^n(a_{i,j}>x)\),则\(f\)单调递减,二分找到使\(rk<f(ans)\)成立的最小的\(ans\in\mathbb{N}\cap[1.n^2]\)即为答案。那怎样求\(f(x)\)呢?

\((1,n)\)出发。对于第\(r\in\mathbb{N}\cap[1,n]\)行第\(c\in\mathbb{N}\cap[1,n]\)列的元素\(a_{r,c}\),我们可以向评测机发起询问。

  • 如果\(a_{r,c}>x\),说明\(\forall i\in\mathbb{N}\cap[r,n]\ (a_{i,c}>x)\),可以令\(c\gets c-1\),再次询问。
  • 如果\(a_{r,c}\leq x\),说明\((r,c)\)恰好是第\(r\)行最后一个小于等于\(x\)的位置,该行一共有\((n-c)\)个大于\(x\)的元素。令\(r\gets r+1\),再次询问。

这样会形成一条从\((1,n)\)出发的路径,每一步要么往下走要么往左走,其中向下走的部分就是小于等于\(x\)的区域的边界。在这个过程中,我们便可以数出各行大于\(x\)的元素的数量,加起来即可。

这样最多枚举\(\lceil\log(n^2)\rceil=\lceil2\log n\rceil\)个答案,每个答案最多查询\(2n\)个值,也就是一共不超过\(2n\lceil2\log n\rceil\approx4n\log n\approx39863\)次查询。

template <typename T, typename Ret, typename Func,
		  typename Cmp = std::less<Ret>>
inline T upperBound(T beg, T end, const Ret &val,
					Func func = Func(), Cmp cmp = Cmp()) {
	while (beg < end) {
		T mid = beg + (end - beg) / 2;
		if (cmp(val, func(mid))) {
			end = mid;
		} else {
			beg = mid + 1;
		}
	}
	return beg;
}

inline size_t countGreater(uint32_t val) {
	size_t row = 1, col = n, res = 0;
	while (row <= n && col) {
		if (query(row, col, val)) {
			res += n - col;
			++row;
		} else {
			--col;
		}
	}
	if (!col) {
		res += (n - row + 1) * n;
	}
	return res;
}

inline void solve() {
	std::cin >> n >> rk;
	answer(upperBound(uint32_t(1), SC<uint32_t>(n * n + 1), rk,
					  countGreater, std::greater<size_t>()));
}

时间复杂度:\(\varTheta(n\log n)\)
空间复杂度:\(\varTheta(1)\)

D. ICPC

The time limit per test for this problem is \(6\ \mathrm{s}\).

You are given an array \(\vec{a}=(a_i)_{i=0}^{n-1}\in\mathbb{N}^n\). In each round, you can take several steps from a given initial position, and in each step you can either move to an adjacent position (i.e. increase or decrease your coordinate by \(1\)) or stay still. When a round is over, the score you get is the sum of values of all unique positions you have visited in this round (including the starting position). For any \(i,j\in\mathbb{N}\) satisfying \(i< n\) and \(j\leq2n\), find out the maximum score \(f_{i,j}\) you can get in a round of \(j\) steps starting at position \(i\).

It is guaranteed that \(n\leq5000\) and \(\forall i\in\mathbb{N}\cap[0,n)\ (a_i\leq10^9)\).

显然对于每个\(i,j\),要想取得最大值,最多反转一次方向,不然就是浪费。

由对称性,我们可以只考虑两种情况(另外两种是对称情况,只需将原数组翻转再用相同的算法计算一遍,两次的结果取\(\max\)即可):

  1. 始终向右走
  2. 先向左走一段,再向右走,且终点不在起点左侧。

事实上,情况1.是情况2.的特例——向左走的距离为\(0\),因此只考虑情况2.即可。

于是

\[f_{i,j}=\max_{k=i-\lfloor i/2\rfloor}^i\sum_{l=k}^{i+(j-2(i-k))}a_l=\max_{k=i-\lfloor i/2\rfloor}^i\sum_{l=k}^{2k+(j-i)}a_l \]

内层循环显然可以用前缀和优化。设\(s_i=\sum_{j=0}^{i-1}a_j\ (i\in\mathbb{N},\ i\leq n)\)\(\vec{a}\)\(i\)项的和,则

\[f_{i,j}=\max_{k=i-\lfloor i/2\rfloor}^i(s_{2k+(j-i)+1}-s_k) \]

现在仍然是\(O(n^3)\)的思路,下面我们想办法将其优化到\(O(n^2)\)。对于固定的的\(d=j-i\),一趟的分数

\[v_{d,k}=s_{2k+d+1}-s_k \]

仅由\(k\)决定,于是最终的分数

\[f_{i,i+d}=\max_{k=i-\lfloor i/2\rfloor}^iv_{d,k}. \]

固定\(d\)而变化\(i\),这就是一个滑动窗口最大值问题。虽然窗口长度不是固定的,但左右边界都是单向移动的,因此实际上化归到了经典的琪露诺那道题,用单调队列优化DP即可。

别忘了翻转数组处理对称的情况。

[2026-01-24] Educational Codeforces Round 45

D. Graph And Its Complement

Given 3 positive ntegers \(n,c,d\), you need to construct an undirected simple graph \(G\) of order \(n\) such that \(G\) and its complement/inverse \(\overline{G}\) have exactly \(c\) and \(d\) connected components, respectively. If there is no graph that satisfies these constraints on a single line, print NO (without quotes). Otherwise, output YES and the adjacency matrix of \(G\). If there are several matrices that satisfy the conditions, you can output any of them.

It is guaranted that \(c,d\leq n\leq1000\).

重要结论:若原图不连通,则补图必连通。

因此如果\(\min\{c,d\}>1\),直接NO即可,这样问题就很简单了。

但是有两个特殊情况\((n,c,d)\in\{(2,1,1),(3,1,1)\}\)是构造不出来的,这个有点靠注意力。一般情况下,只需选出一些孤立点,剩下的点用一条路径连接起来即可。

inline void solve() {
	size_t n, c, d;
	std::cin >> n >> c >> d;
	if ((c != 1 && d != 1) || (n == 2 && c == 1 && d == 1) || (n == 3 && c == 1 && d == 1)) {
		std::cout << "NO\n";
		return;
	}
	std::cout << "YES\n";
	bool flip = (c == 1);
	if (c == 1) c = d;
	for (size_t i = 0; i < n; ++i) {
		for (size_t j = 0; j < n; ++j) {
			bool is_adj = ((i >= c - 1 && j == i + 1) || (j >= c - 1 && i == j + 1));
			if (flip) is_adj = !is_adj;
			std::cout << (i != j && is_adj);
		}
		std::cout << '\n';
	}
}

时间复杂度:\(\varTheta(n^2)\)
空间复杂度:\(\varTheta(1)\)

E. Post Lamps

posted @ 2026-01-24 17:24  我就是蓬蒿人  阅读(7)  评论(0)    收藏  举报