A - Minimum-Maximum Compounds

画出表达式树,不难发现答案就是树上同种操作构成的极大连通块个数。

#include <bits/stdc++.h>
using namespace std;
int main()
{
	freopen("compounds.in", "r", stdin);
	freopen("compounds.out", "w", stdout);
	int T;
	cin >> T;
	while (T--)
	{
		string S;
		cin >> S;
		int ans = 0;
		stack <int> st;
		st.push('#');
		for (int i = 0; i < S.size(); i++)
		{
			if (S[i] == '(' && st.top() != S[i - 1]) ans++;
			if (S[i] == '(') st.push(S[i - 1]);
			if (S[i] == ')') st.pop();
		}
		cout << ans << endl;
	}
	return 0;
}

B - Savings Challenge

写出程序计算所有 (n+1)(m+1)(n + 1)(m + 1) 种状态是必胜态还是必败态。列出表格,观察图形性质,可得:

nmod3=n \bmod 3 = mmod6=m \bmod 6 = 答案
00 00 Sleeping Alligator
11 Sleeping Iguana
22
33 Sleeping Alligator
44
55
11 00 Sleeping Iguana
11 Sleeping Alligator
22 Sleeping Iguana
33 Sleeping Alligator
44 Sleeping Iguana
55
22 00 Sleeping Alligator
11 Sleeping Iguana
22 Sleeping Alligator
33 Sleeping Iguana
44
55
#include <bits/stdc++.h>
using namespace std;
const string names[2] =
{
	"Sleeping Iguana",
	"Sleeping Alligator"
};
const int results[3][6] =
{
	{1, 0, 0, 1, 1, 1},
	{0, 1, 0, 1, 0, 0},
	{1, 0, 1, 0, 0, 0}
};
int main()
{
	freopen("savings.in", "r", stdin);
	freopen("savings.out", "w", stdout);
	int T, n, m;
	cin >> T;
	while (cin >> n >> m) cout << names[results[n % 3][m % 6]] << endl;
	return 0;
}

C - 2048: Python vs. OOM

Subtask 1

下文记 p=30p = 30

众所周知,2a2b=2a+b2^a \cdot 2^b = 2^{a+b},因此魔法是在指数上加 aa

由于最终的指数和一定等于最初的指数和加上 makmak,因此题目等价于最大化:

i=1n(bimodp)\sum _{i = 1} ^n (b_i \bmod p)

根据直觉,对 pp 取模等于不断减去 pp 直至目标小于 pp,因此最大化上面的值,就要尽量减少减去 pp 的次数:每次取 mod p\bmod\ p 最小的 mm 个数字加 aa,最不容易触发「减去 pp」操作。

这一策略不能通过样例的第 6 组测试数据,但可以证明它在子任务 1 下是正确的。

直接借助 std::sort 模拟上述过程的时间复杂度是 O(Tknlogn)O(Tkn \log n),空间复杂度是 O(n)O(n),可以通过子任务 1。

Subtask 2

众所周知,对于题目中的方式,可以先确定每个数字被加的次数 —— 只要次数总和等于 mkmk,并且每个数字被加的次数不超过 kk,就一定存在对应方案。

于是我们可以设 fi,jf_{i, j} 表示前 ii 个数字一共被加 jj 次后这 ii 个数 mod p\bmod\ p 之和的最大值,初始状态为 f0,0=0f_{0, 0} = 0,转移时枚举下一个数字被加的次数即可,最终的最大总和是 fn,mkf_{n, mk}

该算法的时间复杂度是 O(Tnmk2)O(Tnmk^2),空间复杂度是 O(nmk)O(nmk),可以通过子任务 2。

Subtask 3

注意到对一个数进行 pp 次加 aa 操作不会改变它 mod p\bmod\ p 的值。当 kk 很大时,只要确定每个数字被操作的次数 mod p\bmod\ p 的值,使这些值的总和不大于 mkmk 且与 mkmk 在模 pp 意义下同余,就很可能存在对应的方案 —— 具体来说,在这些值的基础上,每次选择一个值加上 pp,直至总和达到 mkmk

上面的「很可能」要求构造方案的过程中不会出现「所有数都大于 kpk - p,而总和还没达到 mkmk」的情况。此时这 nn 个值的总和至少为 n(kp)n(k - p),因此我们有不等式:

n(kp)<mkn(k - p) < mk nknp<mknk - np < mk nkmk<npnk - mk < np (nm)k<np(n - m)k < np k<pnnmk < p \cdot \dfrac{n}{n - m}

在子任务 3 的特殊限制下,nnm2\dfrac{n}{n - m} \le 2,因此 k2pk \ge 2p 时就可以放心使用以上结论:只确定每个数字被操作的次数 mod p\bmod\ p 的值,按照子任务 2 中的 DP 算法求解。

上述 DP 算法的时间复杂度为 O(Tn2p2)O(Tn^2p^2);当 k2pk \le 2p 时需要回退到子任务 2 的解法,时间复杂度为 O(Tnmk2)O(Tnmk^2),在 k2pk \le 2p 的限制下同样不超过 O(Tn2p2)O(Tn^2p^2)

因此该算法的时间复杂度是 O(Tn2p2)O(Tn^2p^2),空间复杂度是 O(n2p)O(n^2p),可以通过子任务 3。

Subtask 4

2m>n2m > n 时,我们可以先把所有数字加上 akak,然后操作变成了「施展 kk 次魔法,每次魔法选择 nmn - m 个数字加上 a-a」。此时我们有 2(nm)<n2(n - m) < n,并且前面所有解法的正确性都不依赖 aa 的任何性质,因此我们可以回退到子任务 3 的解法。

最终的时间复杂度是 O(Tn2p2)O(Tn^2p^2),空间复杂度是 O(n2p)O(n^2p),可以通过子任务 4。

#include <bits/stdc++.h>
using namespace std;
const int N = 30, P = 30, M = N + 12, Q = 2 * N * P + 12;
int b[M], dp[M][Q];
int main()
{
	freopen("python.in", "r", stdin);
	freopen("python.out", "w", stdout);
	int T;
	cin >> T;
	while (T--)
	{
		memset(dp, 0xc0, sizeof dp);
		int n, m, k, a, c, ans = 0;
		cin >> n >> m >> k >> a;
		__int128 sum = (__int128) m * (__int128) a * (__int128) k;
		if (k > 2 * P) c = P - 1;
		if (k <= 2 * P) c = k;
		a %= P;
		for (int i = 1; i <= n; i++)
		{
			cin >> b[i];
			sum += b[i];
			b[i] %= P;
		}
		if (2 * m > n)
		{
			for (int i = 1; i <= n; i++)
				b[i] = (b[i] + 1ll * a * k) % P;
			m = n - m;
			a = (P - a) % P;
		}
		dp[0][0] = 0;
		for (int i1 = 1; i1 <= n; i1++)
			for (int i2 = 0; i2 <= i1 * c; i2++)
				for (int i3 = 0; i3 <= min(i2, c); i3++)
					dp[i1][i2] = max(dp[i1][i2], dp[i1 - 1][i2 - i3] + (b[i1] + a * i3) % P);
		if (k > 2 * P)
			for (int i = 1ll * m * k % P; i <= min(1ll * n * c, 1ll * m * k); i += P)
				ans = max(ans, dp[n][i]);
		if (k <= 2 * P) ans = dp[n][m * k];
		cout << (long long) (4 * ((sum - ans) / P) + 36 * n + 56) << endl;
	}
	return 0;
}

D - The Zero Point

约定:

A=1+52A = \dfrac{1 + \sqrt{5}}{2} B=152B = \dfrac{1 - \sqrt{5}}{2} C=BC = -B D=1+x+2x2+3x3+5x4+8x5+D = 1 + x + 2x^2 + 3x^3 + 5x^4 + 8x^5 + \ldots m=2n1m = 2n - 1

用等比数列求和化简:

$$D = \dfrac{A \cdot \dfrac{1 - (Ax)^{2n}}{1 - Ax} - B \cdot \dfrac{1 - (Bx)^{2n}}{1 - Bx}}{\sqrt{5}}$$

忽略常数系数:

$$E = A \cdot \dfrac{1 - (Ax)^{2n}}{1 - Ax} - B \cdot \dfrac{1 - (Bx)^{2n}}{1 - Bx}$$

x0x \ge 0 时,DD 的每一项都非负,故 D1D \ge 1

x(B,0)x \in (B, 0) 时,上面两项都是正数,故 D>0D > 0

x<1x < -1 时,DD 中偶数次项为负,奇数次项为正,且 2k+12k + 1 次项的绝对值大于 2k2k 次项,故 D<0D < 0

因此方程 D=0D = 0[1,B][-1, B] 内存在实根。

(25 分)

求导:

$$F = A^2\cdot\dfrac{1-2n(Ax)^{2n-1}+(2n-1)(Ax)^{2n}}{(1-Ax)^{2}} - B^2\cdot\dfrac{1-2n(Bx)^{2n-1}+(2n-1)(Bx)^{2n}}{(1-Bx)^{2}}$$$$F = A^2\cdot\dfrac{1+(2n-1)(A^{2n}x^{2n}-A^{2n-1}x^{2n-1})-(Ax)^{2n-1}}{(Ax-1)^{2}}-B^2\cdot\dfrac{1+(2n-1)(B^{2n}x^{2n}-B^{2n-1}x^{2n-1})-(Bx)^{2n-1}}{(Bx-1)^{2}}$$$$F = A^2 \cdot \dfrac{1 - (Ax)^{2n-1}}{(Ax-1)^{2}} - B^2 \cdot \dfrac{1 - (Bx)^{2n-1}}{(Bx-1)^{2}} + A^2 \cdot \dfrac{(2n-1)(Ax)^{2n-1}}{Ax-1} - B^2 \cdot \dfrac{(2n-1)(Bx)^{2n-1}}{Bx-1}$$$$F = A^2 \cdot \dfrac{1 - (Ax)^{2n-1}}{(Ax-1)^{2}} - B^2 \cdot \dfrac{1 + (Cx)^{2n-1}}{(Bx-1)^{2}} + A^2 \cdot \dfrac{(2n-1)(Ax)^{2n-1}}{Ax-1} + B^2 \cdot \dfrac{(2n-1)(Cx)^{2n-1}}{Bx-1}$$

(50 分)

易知:

$$\left( \dfrac{(Tx)^{2n-1}}{Tx-1} \right)' = T(Tx)^{2n-2} \cdot \dfrac{(2n-1)(Tx-1)-Tx}{(Tx-1)^2}$$

经过计算,上式代入 T=AT = AT=CT = C 导数都为负。

因此我们对前两项代入 x=1x = -1,后两项代入 x=Bx = B,得到一个小于等于 FF 的值:

$$G = A^2 \cdot \dfrac{A^{2n-1} + 1}{(A + 1)^2} - B^2 \cdot \dfrac{1 - C^{2n-1}}{(B+1)^{2}} + A^2 \cdot \dfrac{2n-1}{2} - B^2 \cdot \dfrac{(2n-1)C^{4n-2}}{B^2-1}$$

改写:

$$G = A^2 \cdot \dfrac{A^m + 1}{(A + 1)^2} - B^2 \cdot \dfrac{1 - C^m}{(B+1)^{2}} + A^2 \cdot \dfrac{m}{2} - B^2 \cdot \dfrac{mC^{2m}}{B^2-1}$$

(75 分)

注意到 1<B<0-1 < B < 0m>0m > 0,因此第一项和第三项随 mm 递增而递增,而第四项恒为正数,第二项大于 B2(B+1)2-\dfrac{B^2}{(B+1)^2}

舍弃 GG 的第四项,替换 GG 的第二项,得到一个小于 GG 的值:

$$H = A^2 \cdot \dfrac{A^m + 1}{(A + 1)^2} - \dfrac{B^2}{(B+1)^2} + A^2 \cdot \dfrac{m}{2}$$

于是 HH 关于 nn 单调递增。

代入 n=2n = 2 对应的 m=3m = 3,计算得 H>0H > 0,从而 G>0G > 0,于是 DD[1,B][-1, B] 上单调递增,方程 D=0D = 0 存在唯一实根。

n=1n = 1 的情形显然成立,故原命题得证!

(100 分)