Loading

Codeforces 专区

Codeforces Round #932(Div.2)

怎么只会 A 啊。

\(\text{Problem A}\)

题目大意

对于一个字符串 \(s\),可以进行 \(n\) 次操作(\(n\) 为偶数),每次操作有两种形式:

  1. \(t\)\(s\) 的反串,\(s = s + t\)
  2. \(t\)\(s\) 的反串,\(s = t\)

要求操作完后 \(s\) 的字典序最小,并输出 \(s\)

\(1 \le n \le 10^9, 1 \le |s| \le 100\)

题目思路

考虑到一个字符串越短越好,所以我们尽量是用第二种形式的,发现如果 \(s\)\(s\) 的反串的字典序要小,那么进行 \(n\) 次操作 \(2\) 后必然还是 \(s\),显然是字典序最小的。

但是如果 \(s\)\(s\) 的反串的字典序要大,那么显然最优的做法是第一次进行操作 \(1\),后面进行操作 \(2\),否则到最后就反不到字典序最小的串了,具体来说,答案就是 \(s\) 的反串拼上 \(s\)

\(\text{Problem B}\)

题目大意

给你一个长度为 \(n\) 的序列 \(a\),要求分成若干段(段数不为 \(1\)),使得每段的 \(\text{mex}\) 相同。

\(1 \le n \le 10^5, 0 \le a \le n\)

题目思路

对于区间仔细分析后发现是可以合并的,具体来说:

  • 对于 \(\text{mex}(i, k) = \text{mex}(k + 1, j) = x\),可以得出 \(\text{mex}(i, j) = x\)

简单证明一下就是考虑 \([i, k]\) 中没有出现 \(x\)\([k + 1, j]\) 中也没有出现 \(x\),那么 \([i, j]\) 中也没有出现 \(x\),因此得 \(\text{mex}(i, j) = x\)

那么问题就变得很简单了,因为划分 \(k\) 段合法是划分 \(2\) 段合法的充分条件,所以只要能划分出 \(2\) 段就可以了,预处理前缀/后缀 \(\text{mex}\) 就好了。

\(\text{Problem C}\)

题目大意

给你 \(n\) 个二元组 \((a_i, b_i)\),要求从中选出 \(k\) 个二元组并任意打乱,设其下标集合 \(S = \{p_1, p_2, ..., p_k\}\),要求在 \(\sum\limits_{i = 1}^k a_i + \sum\limits_{i = 2}^k |b_{p_i} - b_{p_{i - 1}}| \le l\) 的情况下将 \(k\) 最大化。

\(1 \le n \le 2000\)

题目思路

我们考虑一个事情,如果选出了 \(k\) 个且下标集合 \(S = \{p_1, p_2, ..., p_k\}\),那么当 \(p_1 \le p_2 \le ... \le p_k\) 的时候是这个集合所有顺序排列中值最小的,此时的代价是 \(\sum\limits_{i = 1}^k a_i + b_{p_k} - b_{p_1}\)

因此我们考虑枚举这个集合中的下标最小值和下标最大值,在这中间,很明显元素是按照 \(a\) 的大小从小往大放,直到放到不能放为止,这可以用堆来做,发现是三方的,然后我们在枚举最大值的时候顺便加进去计算,时间复杂度就是 \(O(n^2 \log_2 n)\)

\(\text{Problem D}\)

题目大意

给定一个大小为 \(n\) 的集合 \(S\),其中元素大小 \(\le c\),问满足以下条件的数对 \((x, y)\) 的个数有多少对:

  1. \(x, y \in \mathbb{Z}, 0 \le x \le y \le c\)
  2. \(x + y \notin S, y - x \notin S\)

\(1 \le n \le 3 \times 10^5, 0 \le c \le 10^9\)

题目思路

首先发现这个一看就很容斥的样子,考虑容斥完我们要计算什么:

\[ans = \sum_{i = 0}^c \sum_{j = i}^c 1 - \sum_{i = 0}^c \sum_{j = i}^c [i + j \in S] - \sum_{i = 0}^c \sum_{j = i}^c [j - i \in S] + \sum_{i = 0}^c \sum_{j = i}^c [i + j \in S] \times [j - i \in S] \]

考虑第一项的值,就是 \(\frac{(c + 1)(c + 2)}{2}\)

考虑第二项的值,发现对于每一个 \(i \le \frac{s_i}{2}\),都有一个与之对应的 \(j\),就是 \(\sum\limits_{i = 1}^n \left(\frac{s_i}{2} + 1\right)\)

考虑第三项的值,发现对于每一个 \(s_i \le i \le c\),都有一个与之对应的 \(j\),就是 \(\sum\limits_{i = 1}^n \left(c - s_i + 1\right)\)

考虑第四项的值,在此之前,我们要想明白一个事情,对于一对 \((i, j)\) 如果产生贡献,那么只会对应到一组 \((s_x, s_y)\) 上,换句话说,\(i = \frac{s_x - s_y}{2}, j = \frac{s_x + s_y}{2}\)当且仅当满足这个条件,才会对答案产生贡献,不难发现就是奇数的 \(s\) 两两组合,偶数的 \(s\) 两两组合。

然后直接计算即可。

Codeforces Round #919(Div.2)

怎么只会 A, B, D 啊。

感觉越打越智慧了。

\(\text{Problem A}\)

题目大意

给你 \(n\) 个限制,有下面三种形式:

  • \(x\) 要大于等于给定数 \(k\)
  • \(x\) 要小于等于给定数 \(k\)
  • \(x\) 要不等于给定数 \(k\)

问你满足条件的整数 \(x\) 有多少个。

\(1 \le n \le 100\)

题目思路

这个很显然就是求出前两种限制的限定范围,然后看这个限定范围内有多少数不可以选,然后就没了。

\(\text{Problem B}\)

题目大意

Alice 和 Bob 轮流操作一个长度为 \(n\) 的序列 \(a\),操作如下:

  • Alice 可以选取 \(k\) 个数字并删掉它们。
  • Bob 可以选取 \(x\) 个数字使它们乘上 \(-1\)

现在 Alice 先操作一次,Bob 后操作一次,Alice 想要最大化 \(a\) 的总和,Bob 想要最小化 \(a\) 的总和,问你最终 \(a\) 的总和是多少(Alice 和 Bob 都绝顶聪明)。

\(1 \le n \le 2 \times 10^5\)

题目思路

考虑这么一个事情,那就是在 Alice 操作完后,Bob 一定会选择 \(a\) 中最大的 \(x\) 个数使其变为相反数,那么只需要在 Alice 的所有取数情况中对最终情况求一个最大值即可。不难发现,Alice 要阻止 Bob 选择大的数,就要删掉最大的一段前缀,但是删多了可能会不优,所以你去枚举删了多少个最大的前缀,再计算 Bob 最优取什么,最后在所有情况中取最大就好了。

\(\text{Problem C}\)

题目大意

对于一个长度为 \(n\) 的序列 \(a\),定义一个 \(n\) 的正因子 \(k\) 产生贡献当且仅当:

  • 存在 \(m > 2\),使得令 \(a_i = a_i \bmod m\) ,并把 \(a\) 依次分成 \(\frac{n}{k}\) 个子串后,这 \(\frac{n}{k}\) 个子串的每个位置的值依次相等。

问你有多少个 \(k\) 能产生贡献。

\(1 \le n \le 2 \times 10^5\)

题目思路

这个题妙妙。

考虑到 \(n \le 2 \times 10^5\),我们去枚举 \(n\) 的因子 \(k\)\(sqrt n\) 级别的),不难发现的一个性质就是如果 \(x \bmod m = y \bmod m(x > y)\),那么 \(m | x - y\),所以,我们对于每一个 \(|a_{i + k} - a_i|\) 求最大公因数!这样每个位置的条件就都满足了,如果最大公因数等于 \(1\),那就是不可行的。

不难得出时间复杂度为 \(O(n \sqrt n)\),实际上,这个复杂度只是上界,真实复杂度远远低于此复杂度(因为 \(\gcd\) 大概只需要 \(2 \log V\) 次就可以得到 \(1\))。

\(\text{Problem D}\)

题目大意

对于一个最开始为空的序列 \(a\),有 \(n\) 次操作:

  • 向末尾添加 \(x\)
  • 复制 \(x\)\(a\) 并添加到末尾。

\(q\) 次询问,每次询问第 \(k\) 个位置的数是多少。

\(1 \le n \le 10^5, 1 \le k \le 10^{18}\)

题目思路

最为简单的一道题目,一中好像考过加强版?

考虑到 \(2\) 操作最多只有 \(59\) 次,所以考虑直接暴力。

但是 \(1\) 操作可能会有很多次,该怎么办呢?考虑直接把相邻的 \(1\) 操作捆绑在一起,然后进行计算,这一步你可以直接计算操作完后的长度取模,也可以直接二分。

Codeforces Round #917(Div.2)

\(\text{Problem B}\)

题目大意

给定一个字符串 \(s\),每次只能删第一个字符或者第二个字符,问任意次操作后能得出多少个不同的非空串。

题目思路

这个题妙妙妙。

考虑到进行操作后只可能是一段后缀加前面的某个字符,又因为每个后缀长度不同,所以直接枚举即可。

\(\text{Problem C}\)

题目大意

自己可以看原题。

题目思路

考虑到如果 \(a_i\) 全为 \(0\),肯定交替进行。

如果又初始值,那么初始操作不会超过 \(2n\) 次,否则就可以用全为 \(0\) 的做法代替了(因为一次贡献不超过 \(n\))。

Codeforces Round #772(Div. 2)

\(\text{Problem A}\)

题目大意

自己可以看原题。

题目思路

考虑到 \(a | b \le a + b\),所以最优方案当然是一个赋值为 \(0\),另一个赋值为 \(p_i | p_j\),答案就是全部 \(p_i\) 或起来。

\(\text{Problem B}\)

题目大意

自己可以看原题。

题目思路

对于本题,显然,如果 \(a_i\) 是那个数,那么可以 \(a_{i + 1} = \max ( a_i, a_{i + 2 } )\),这样一次就能消掉两个数了,是最优的。

\(\text{Problem C}\)

题目大意

自己可以看原题。

题目思路

首先观察样例不难发现,如果在 \(a\) 不有序的情况下,若 \(a_{n - 1} > a_{n}\) 或者 \(a_{n} < 0\),那么无解。

考虑为什么,首先第一种是好证的,因为 \(a_{n - 1}\) 无法通过任意一次操作更改,而 \(a_{n} < 0\) 则是因为那样的话 \(a_{n - 2}\) 就填不了了。

然后考虑将前面 \(n - 2\) 个数全部赋值为 \(a_{n - 1} - a_{n}\),就做完了(这也是为什么不能 \(a_n < 0\) 的原因)。

\(\text{Problem D}\)

题目大意

自己可以看原题。

题目思路

考虑每一次就是在二进制末尾加 \(00\) 或者 \(1\),进行 DP 判断加了多少位的方案数,发现是斐波那契数列,然后考虑如何处理重复的问题,如果一个数 \(x\),删除了末尾可以删除的二进制位后,可以变为另外的个数(广义包含),那么就可以把这个数去掉,否则就保留。

贪心的想,先排序,最小的数一定会带来最大的贡献。

Codeforces Round #727(Div. 2)

只会 A B C 捏。

\(\text{Problem A}\)

题目大意

自己可以看原题。

题目思路

考虑每个点对答案的贡献,不难发现是:

\[\sum_{i = 1}^{n} \min (\lfloor \frac{t}{x} \rfloor, n - i ) \]

解释一下就是,我第 \(i\) 个点后面最多有这么个可能被统计到答案里的。

不难发现是一段相等的数和一个等差数列,求和就完了。

\(\text{Problem B}\)

题目大意

自己可以看原题。

题目思路

直接前缀和维护就完了。

\(\text{Problem C}\)

题目大意

自己可以看原题。

题目思路

考虑每次就是连续一段数分组,每次想当于是花若干代价将两段连接起来,在贡献相等的情况下,当然是越小越好,所以按照这个贪心就好了。

\(\text{Problem D}\)

题目大意

自己可以看原题。

题目思路

考虑按照 \(b\) 从大到小排序,因为越小的就越要选。

然后在拿的过程中要注意能否拿 \(b\) 小的了,能拿就拿(也可以拿一部分 \(b\) 大的,再拿 \(b\) 小的),排完序后发现是一个类似双指针的结构,然后扫一遍就做完了。

Codeforces Round #569(Div. 2)

\(\text{Problem A}\)

题目大意

自己可以看原题。

题目思路

考虑其是由四个阶梯型组合而成,再把多余的给去掉就好了。

\(\text{Problem B}\)

题目大意

自己可以看原题。

题目思路

考虑把所有数都变为负数,然后如果是奇数那么就选绝对值最大的数取正(可以证明减少贡献最小),然后就没了。

\(\text{Problem C}\)

题目大意

自己可以看原题。

题目思路

CF 出原题?

考虑经过最多 \(n\) 轮,最大值一定在队首,然后后面都是循环的,分两种类讨论就好了。

Codeforces Round #666(Div. 2)

\(\text{Problem A}\)

题目大意

自己可以看原题。

题目思路

发现此要求等价于所有字母出现次数都能被 \(n\) 整除,然后没了。

\(\text{Problem B}\)

题目大意

自己可以看原题。

题目思路

考虑到合法的 \(c\) 非常小,大概只有 \(10^15\)\(n\) 次方根那么大,然后就没了。

\(\text{Problem C}\)

题目大意

自己可以看原题。

题目思路

构造题。

考虑刻画这一本质,就是最后一定有一次 \([1, n]\) 操作。

然后我们把 \([1, 1]\) 加上 \(n - a_1\),然后 \([2, n]\) 加上 \(( n - 1 ) \times a_i\),然后最后进行一次操作就能全部变为 \(0\) 了。

\(\text{Problem D}\)

题目大意

自己可以看原题。

题目思路

首先如果最大的一堆要比其它的大,那么肯定先手赢。

然后判断奇偶性,如果是奇数就是先手赢,偶数就是后手赢。

Codeforces Round #509(Div. 2)

\(\text{Problem A}\)

题目大意

自己可以看原题。

题目思路

发现最差一定是买了 \(\max - \min\) 个键盘,然后减去没被抢的,就是被抢的了。

\(\text{Problem B}\)

题目大意

自己可以看原题。

题目思路

首先把 \(c, d\) 都除以最大公约数,然后再二分最多能乘多少,取个最小值就好了。

\(\text{Problem C}\)

题目大意

自己可以看原题。

题目思路

肯定是能选小的就选小的,然后用 set 模拟贪心的过程,二分一下就好了。

\(\text{Problem D}\)

题目大意

自己可以看原题。

题目思路

这个肯定就最优肯定是从一段上升区间开头的,然后维护下前缀和,二分一下,注意一下细节就好了。

\(\text{Problem E}\)

题目大意

自己可以看原题。

题目思路

不难证明,如果能构造出一棵非链树,那么一定可以构造出一种链。

然后构造链就贪心的去选就好了,不难发现始终有一个数是 \(n\)

Codeforces Round #495(Div. 2)

\(\text{Problem A}\)

题目大意

自己可以看原题。

题目思路

考虑钦定 \(x\) 为到新建酒店最小的,那么一共就只有 \(2 \times n\) 种新建酒店的方式,暴力枚举就好了。

\(\text{Problem B}\)

题目大意

自己可以看原题。

题目思路

考虑基本不等式,\(0\)\(1\) 的差最小是最好的,那么我们选择 \(01\) 交替填,容易发现给的询问没有屁用。

\(\text{Problem C}\)

题目大意

自己可以看原题,

题目思路

发现只有一种数的最后一个数的贡献最容易统计,记录一下前缀出现不同的数的个数就好了。

\(\text{Problem D}\)

题目大意

自己可以看原题。

题目思路

我写了题解,可以去看,CF1004D。

Codeforces Round #404(Div. 2)

\(\text{Problem A}\)

题目大意

自己可以看原题。

题目思路

就直接模拟就好了。

\(\text{Problem B}\)

题目大意

自己可以看原题。

题目思路

贪心的想,肯定是选越远越好的,然后求一下最大最小就做完了。

\(\text{Problem C}\)

题目大意

自己可以看原题。

题目思路

首先如果 \(n \le m\),那么直接输出 \(n\)

如果 \(n > m\),那么前 \(m\) 天肯定平安无事,从后面开始满足单调性,然后二分就可以了。

注意高精度。

\(\text{Problem D}\)

题目大意

自己可以看原题。

题目思路

首先我们枚举前一半的终止位置在哪里,然后钦定这个位置为最后一个,那么位置 \(i\) 答案就是:

\[\sum_{i = 0}^{min ( a - 1, b - 1 )} C_{a - 1}^i \times C_{b - 1}^{i + 1} \]

然后我们把组合数的第一个利用对称性转化,然后利用范德蒙德卷积的标准形式进行整合,就可以做到 \(O(n)\) 了,这个东西我特意在 Trick 合集里写了。

Codeforces Round 965 (Div. 2)

每一道题目应该被铭记,每一次思考应该被珍惜。

\(\text{C}\)

题目大意

自己可以看原题。

题目思路

考虑讨论一下贡献,发现除了非中位数位置上的数都是 \(a_i + a_mid\),这样的话我们当然是选一个最大值最好。

然后有 \(k\) 次操作,我们一定只有两种分配方式:

  • 全部分配给最大值。
  • 全部分配给中位数。

因为如果两者都分配很明显肯定不是最优的。

然后如果要增加最大值我们就直接选一个最大的 \(b = 1\) 的元素一直磊就好了。

如果要增加中位数的话这个问题不太好处理,我们,可以二分最大的中位数,这样一定是每次把最大的 \(b = 1\) 挪到前面来(就是选择 \(< x\)\(b = 1\) 的数一直增加到 \(x\)),然后我们 Check 一下中位数是否 \(> ans\),然后就可以二分了,这个东西很明显具有单调性但是我没有做出来。

posted @ 2024-03-07 17:19  Alexande  阅读(146)  评论(0)    收藏  举报