\[\large \text{Round 1 : Educational Codeforces Round 120 (VP)} \]
一言:
孤独的人不会伤害别人,只会不断地伤害自己罢了。
——我的青春恋爱物语果然有问题
\(\text{C: Set or Decrease }\)
后四题唯一场切题,(别问我为什么只有这一道)。
读完题之后,理一下思路,可以很容易的想到一种贪心思想,就是我们找到这个序列中最小的数,对他执行 \(x\) 次操作 \(1\),然后找到 \(m\) 个最大的数,将他们与最小的数执行一次操作 \(2\),这样必然是最优的。($ 0 \le x, 0 \le m \le n - 1$)。
首先对于符合题意的序列,输出 \(0\) 直接跳过。
接着我们求出要使得总和小于给定总和总共需要减去的数,即 \(sum - k\),设为 \(need\) 。然后定义 \(b\) 数组表示 \(b_i=a_i-a_1\),以及 \(sum_i\) 表示 \(b\) 数组的后缀和。
所以我们显然有 \(b_{n-m+1}+x \times (m+1) \ge need\)。
由于 \(x\) 可能很大,所以我们可以直接考虑枚举 \(m\),求得最小的 \(x\),然后将 \(m+x\) 取最小值即可。
\(\text{D: Shuffle}\)
对于这道题,我们可以非常容易的通过 \(n^2\) 的复杂度找到可以修改的所有区间,并对其进行修改。
但是很显然,这样是有重复的,这也是本道题的难点。
但是实际上,我们并不关心具体是那个区间修改了,我们可以直接枚举发生变化过的所有区间 \([l,r]\),如果两个端点保证改变了,那他就必然可以保证会与其他区间的变化不一样,所以接下来的目标就是要求对于区间 \([l,r]\),保证端点修改的方案数。(可以发现,只有 \([l,r]\) 之间 \(1\) 的个数小于等于 \(k\),且全局 \(1\) 的个数大于等于 \(k\),它才会被修改。)
对于 \(a_l,a_r\),必须填上与其原来不同的 \(0,1\),(如果填不上就特判无解),定义还可以填的 \(0,1\) 的个数分别为 \(num0,num1\),则方案就是 \(C(num0+num1,num0)\)。
最后累加起来就可以了。
\(\text{E: Math Test}\)
看见这个绝对值就很不爽,我们可以考虑对于每个人定义一个数组 \(c_i \in \{ -1,1 \}\),并暴力搜索得到每个人的 \(c_i\) 是 \(-1\) 还是 \(1\)。
那么,我们就可以把答案重新定义为 \(\sum ^n _{i=1} c_i \times (r_i - x_i)\),假设第 \(i\) 道题目的得分为 \(e_i\),\(a_{i,j}\) 表示第 \(i\) 个人的是否答对了第 \(j\) 道题。
接着我们对这个式子进行一系列的恒等变形:
\[\begin{aligned} ans&=\sum ^n _{i=1} c_i \times (r_i - x_i) \\ &=\sum ^n _{i=1} c_i \times r_i - \sum ^n _{i=1} c_i \times x_i\\ &=\sum ^n _{i=1} c_i \times r_i - \sum ^n _{i=1} c_i \times \sum _{j=1} ^ m a_{i,j} \times e_j\\ &=\sum ^n _{i=1} c_i \times r_i - \sum ^m _{i=1} \left( \sum _{j=1} ^ n a_{j,i} \times c_i\right) \times e_j \end{aligned} \]可以发现,减号之前部分是定值,右边括号内也是定值,要使右边减的越小,则根据排序不等式,则括号内值越小,\(e\) 的值就越大。
虽然但是,这样并没有结束,你会发现有一些不合法的方案,就是你求出来 \(e\) 之后,还原回去,会发现他绝对值取正负并不与 \(c\) 数组匹配,也就是有可能存在一个人他的 \(c_i \times (r_i-x_i)\) 可能是个负数。但显然,如果他是个负数,那么将 \(c\) 数组取反就必然会得到正确的答案,也就是说,必然会有其他情况比该情况更优,所以这个不合法情况永远成不了最优解。
所以最终复杂度 \(2^nmn+2^nm\log m\) 在 CF 神机下乱过。
\(\text{F: Quadratic Set}\)
题目给到了两个关键信息,阶乘的连乘,完全平方数。那我们就希望能不能将阶乘的连乘简化为一个完全平方数再乘一些数。
实际上还真就可以简化。有以下恒等式:
\(\prod _{i=1} ^ {2k} i! = \left (\prod_{i=1}^k (2k-1)! \right)^2 \times 2^k \times k!\)
因为 \(\left(\prod_{i=1}^k (2k-1)! \right)^2= \prod_{i=1}^k (2k-1)! \times (2k)! \times \dfrac{1}{2k}\) ,还是比较好推的,就是确实不太好想到。
然后我们在通过一系列的样例观察,发现好像至少可以选出 \(n-3\) 个数,那我们根据上面的恒等式来证明一下。
首先对于 \(4 \mid n\),那我们令 \(k=\dfrac{n}{2}\),则只需要删去 \(\dfrac{n}{2}\) 即可符合条件。
接着对于剩余的 \(2\mid n\),我们仍然令 \(k=\dfrac{n}{2}\),则只需要删去 \(2,\dfrac{n}{2}\),即可符合条件。
对于剩余情况,显然 \(n\) 是奇数,我们令 \(k = \dfrac{n-1}{2}\),则只需要删去 \(2,\dfrac{n-1}{2},n\) 即可符合条件。
所以得证,但是并不一定是最优解。
我们定义 \(A=\prod _{i=1} ^ {n} i!\)
如果 \(A\) 是平方数,则输出所有的 \(n\) 个数。
接着枚举 \(1 \le i \le n\),如果 \(\dfrac{A}{i!}\) 是平方数,则输出 \(n-1\) 个除了 \(i\) 的数。
接着枚举 \(1 \le i \le n\),如果能够找到 \(j\) 满足 \(\dfrac{A}{i! \times j!}\) 平方数,则输出 \(n-2\) 个除了 \(i,j\) 的数。
否则输出 \(n-3\) 个不是 \(\dfrac{n-1}{2},2,n\) 的数。
但是你总不可以暴力求阶乘吧? 实际上,每个阶乘是不是平方数只与其的质因数分解后,每个质因数的个数是不是偶数有关,想到偶数,你是否有想到异或?
我们可以考虑给每个质因子赋一个哈希值,定义一个阶乘的 \(a_i\) 表示 \(i\) 的阶乘中质因数分解后所有质数哈希值的异或和。(如果每个质数有多个,那就都异或起来)显然可以递推处理。
显然,如果 \(B=a_1 \oplus a_2 ... \oplus a_n=0\),则就满足最初的 \(A\) 是平方数。如果 \(B \oplus a_i = 0\),也就找到了\(\dfrac{A}{i!}\) 是平方数。对于最后一种情况,可以用 \(map\) 处理,即每次将 \(a_i \oplus B\),放入 \(map\) 中,每次查 \(map\) 中是否存在 \(a_i\),一旦存在就满足\(\dfrac{A}{i! \times j!}\) 平方数。
时间复杂度 \(n\log n\)。
\(\text{What I learned:}\)
-
如果你发现当你求方案加和时存在重复方案,则可以考虑将每次将要求解的子问题多限定一些条件达到去重目的。
-
你要求最值,但是通过你的办法求出时可能存在不满足题目条件的,那你可以想想这些解有没有可能是最优的。
-
多观察样例找规律。
-
\(\prod _{i=1} ^ {2k} i! = \left (\prod_{i=1}^k (2k-1)! \right)^2 \times 2^k \times k!\) 。
-
排序不等式。
-
如果要看一个数出现了奇数次还是偶数次,请别忘记异或。
-
如果判断一个数出现次数的奇偶性仅仅通过异或的话,可能会出现另外的数把当前数给异或掉了,所以此时可以考虑哈希来尽量避免这种重复。