T1 sun
暴力枚举即可
时间复杂度分析:
\((lnx)' = \frac{1}{x}\)
根据牛顿-莱布尼茨公式可得:
\(\sum_{x = 1}^{n}{\frac{1}{x}} = \int_{1}^{n}{\frac{1}{x}} = ln(n) - ln{1} = ln(n)\)
令 \(ln(n) = k\) 可得:
\(n = e^{k} <= e^{15} \approx 3269017\)
T2 order
首先需要理解题意
再模拟可得:
\(1\) \(1\)
\(1\) \(10\)
\(2\) \(101\)
\(3\) \(10110\)
可以观察到:
第 \(i\) 次变化后的序列是由第 \(i - 1\) 次和第 \(i - 2\) 次的序列拼接而成
易联想到斐波拉契数列
即第 \(i\) 次变化后序列中 \(1\) 的个数等于 \(f_{i}\)
对于每次询问:
区间 \(a\)~\(b\) 中 1 的个数可用前缀和的思想求解
即 \(ans = sum_b - sum_{a - 1}\)
对于 \(sum_i\)
根据上述拼接的思想
区间 \(1\)~\(i\) 由子序列拼接而成,其中所有子序列的长度和等于 \(i\),且是某次变化后得到的序列
如:区间 \(1\) ~ \(4\) 可由 \(101\) 和 \(1\) 拼接而成,\(sum_{4} = 2 + 1 = 3\)
代码实现
同样是根据我们最初的思想
对于区间 \(1\) ~ \(x\) 它必是由两部分组成:
一段完整的上一次变化得到的序列和一段大概率不完整的上上次变化得到的序列的前一部分
因此我们对斐波拉契数列进行预处理,每次找出前一段完整的序列递归的进行求解
Tip
可以预处理到 \(f_{100} \approx 2^{62}\)
时间复杂度分析
因为每次可以使序列减少一半多(前一段序列长度大于后一段序列长度),所以单次询问小于 \(log_{2}{n}\)
T3 queue
观察数据规模:
根据题意用队列模拟即可
T4 toothpick
今天的压轴题目
核心目标
要使 \((a_i - b_i) ^ 2\) 更小,那么就要使 \(a_i - b_i\) 更小
也就是说在最小的移动步数下,将 \(a\) 序列 和 \(b\) 序列中大小排名相同的数交换到同一个位置
问题转化
首先对 \(a\) 序列和 \(b\) 序列进行离散化方便我们之后的操作
注意:如果数据有重复需要去重
当我们进行离散化后,若 \(a\) 序列和 \(b\) 序列中大小排名相同的数全部被交换到了对应的同一个位置
那么此时的 \(a\) 序列和 \(b\) 序列是完全相同的
建立一个从 \(a\) 到 \(b\) 的映射集 \(f\)
令 \(f[a[i]] = b[i]\) 若序列 \(a\) = \(b\) 那么 \(f[a[i]] = b[i] = a[i]\)
即 \(f[i] = i\) (注意此处的 \(i\) 和上文的 \(i\) 不是同一个 \(i\))
那么该问题就转化为了将 \(f\) 变为正序所需要的最小交换次数
也就是:逆序对!