找出满足差值条件的下标 I
同下。
最短且字典序最小的美丽子字符串
滑动窗口。
1 | class Solution { |
找出满足差值条件的下标 II
维护最大值和最小值就行。
1 | class Solution { |
构造乘积矩阵
前后缀分解,将二维数组看作一维数组。
1 | class Solution { |
同下。
滑动窗口。
1 | class Solution { |
维护最大值和最小值就行。
1 | class Solution { |
前后缀分解,将二维数组看作一维数组。
1 | class Solution { |
模拟。
1 | class Solution { |
贪心。
1 | class Solution { |
和最长递增子序列有点像,处理的时候记录一下路径就好。
1 | class Solution { |
明显是多重背包问题,求背包中物品重量在 \([l,r]\) 之间的方案数,朴素的转移方程为:
这样做的时间复杂度为 \(O(rn)\),其中 \(n\) 为 \(nums\) 的长度。在题目的数据范围下,复杂度达到 \(4\cdot 1e8\) 数量级,会导致超时。优化方式如下,当 \(j\geq(cnt[i]+1)\cdot w[i]\) 且 \(w[i]\neq 0\) 时,有:
然后错位相减,得到:
当 \(j\geq(cnt[i]+1)\cdot w[i]\) 且 \(w[i]=0\) 时,直接使用朴素转移方程,得到:
同理可得,当 \(w[i]\leq j<(cnt[i]+1)\cdot w[i]\) 时,错位相减得到:
当 \(j<w[i]\) 时,直接使用朴素转移方程,得到:
这样做的时间复杂度为 \(O(r\sqrt{S})\),其中 \(S\) 表示 \(nums\) 的元素和,\(\sqrt{S}\) 表示 \(nums\) 中不同元素的最大数量。不同元素的最大数量满足 \(\frac{(0+(x-1))\cdot x}{2}\leq S\),解得 \(x\leq \frac{1+\sqrt{1+8\cdot S}}{2}\)。还有一些常数级别的优化,比如减少遍历的上界等。
1 | class Solution { |
分开处理,先做前缀和,再倒序减去某个前缀和,就可以不使用辅助数组 \(g\):
1 | class Solution { |
Educational Codeforces Round 156 (Rated for Div. 2)
当 n <= 6 || n == 9
时,不能凑出三个不同的不能被 \(3\) 整除的正整数,其他情况均可以通过以下方式凑出。
1 | public static void solve() { |
可以分为四种情况:点 \(O\) 和 点 \(P\) 在圆 \(A\) 内/上;点 \(O\) 和 点 \(P\) 在圆 \(B\) 内/上;点 \(O\) 和 点 \(P\) 分别在圆 \(A\) 和圆 \(B\) 内/上,并且圆 \(A\) 和圆 \(B\) 相切/相交;点 \(O\) 和 点 \(P\) 分别在圆 \(B\) 和圆 \(A\) 内/上,并且圆 \(A\) 和圆 \(B\) 相切/相交。
方法一:浮点二分
1 | public static void solve() { |
方法二:直接计算
1 | public static void solve() { |
二分删除的字符数 \(p\),可以通过计算得到 \(q=pos-\frac{(n+(n-p+1))\cdot p}{2}\),则答案为 \(s_{1+p}[q]\),可以使用单调栈删除字符,然后获取答案即可。
1 | public static void solve() { |
很容易想到当 s[0] == '?'
时,方案数为 \(0\),并且 >
和 <
符号的位置放什么数都是确定的,也就是说只有 ?
位置对答案有贡献。分别考虑每个 ?
位置(从位置 \(1\) 开始,因为位置 \(0\) 不能是 ?
),假设该位置的下标为 \(i\),那么它是第 \(i+2\) 个的数(因为添加第 \(1\) 个数时,不会记录字符到 \(s\) 中,并且下标从 \(0\) 开始,所以加 \(2\)),第 \(i+2\) 个数必须要大于前 \(i+1\) 个数的最小值,小于前 \(i+1\) 个数的最大值。我们可以将前 \(i+1\) 个数排成有序的序列,然后根据大小将第 \(i+2\) 个数插入到序列中,总共有 \(i+2\) 个插入位置,但在限制条件下,我们只能选择 \(i\) 个位置进行插入,对所有 ?
位置累乘 \(i\) 即可得到当前字符串的插入方案数。
看半天才懂,很多题解只提到插入法,根本没提到有序序列,只要知道是根据大小插入就很简单了。也就是说,插入时根本不关心当前是什么数,只关心当前数在前面数的最大值和最小值之间。在将所有的数插入完成后,所有 ?
位置是什么数就随之确定,也就确定了一种方案。
1 | private static final int MOD = 998244353; |