首发于彼得攀的小站
查阅更多的题解,请点击
github传送门 (求个star哇)
A. Book Reading
Solution
解法
本题如果采用暴力求解,最坏情况下,每个读者都需要 O ( n ) O(n) O(n) time, 则总的时间复杂度为 O ( n q ) O(nq) O(nq) time. (一个简单的例子,q个读者对应的 R i R_i Ri都是1,那么每个读者都要算n次)
为了避免上述暴力过程中出现的重复计算,可以将结果提前存下来, c o u n t ( i ) count(i) count(i)代表i的倍数且未被撕掉页的个数。那么计算整个count数组需要 N + N / 2 + N / 2 + ⋯ + 1 = N ( 1 + 1 / 2 + 1 / 3 + ⋯ + 1 / N ) N+N/2+N/2+\cdots+1=N(1+1/2+1/3+\cdots+1/N) N+N/2+N/2+⋯+1=N(1+1/2+1/3+⋯+1/N):
其中的 N ( 1 + 1 / 2 + 1 / 3 + ⋯ + 1 / N ) N(1+1/2+1/3+\cdots+1/N) N(1+1/2+1/3+⋯+1/N)是调和数, H n = 1 + 1 2 + 1 3 + ⋯ + 1 n = ∑ k = 1 n 1 k H_{n}=1+\frac{1}{2}+\frac{1}{3}+\cdots+\frac{1}{n}=\sum_{k=1}^{n} \frac{1}{k} Hn=1+21+31+⋯+n1=∑k=1nk1,利用极限可以得到 lim n → ∞ ( ∑ k = 1 n 1 k − ln n ) = γ \lim _{n \rightarrow \infty}\left(\sum_{k=1}^{n} \frac{1}{k}-\ln n\right)=\gamma limn→∞(∑k=1nk1−lnn)=γ,最终有 H n ∼ ln n + γ H_{n} \sim \ln n+\gamma Hn∼lnn+γ
所以整个算法的时间复杂度为 O ( n l o g n + q ) O(nlogn+q) O(nlogn+q) time.
复杂度分析
见上, O ( n l o g n + q ) O(nlogn+q) O(nlogn+q) time
代码
B. The Equation
Solution
解法
这道题思路很清晰:将 A i A_i Ai转化为二进制表示, ( A 1 x o r k ) + ( A 2 x o r k ) + ⋯ + ( A k x o r k ) (A_1\ xor\ k)+(A_2\ xor\ k)+\cdots+(A_k\ xor\ k) (A1 xor k)+(A2 xor k)+⋯+(Ak xor k)仅由二进制表示中,每位上1的个数和k对应位置取值(0或1)决定,令 c o u n t ( i ) count(i) count(i)为二进制表示中第 i i i位(由低到高标号,从0开始)1的个数, c o u n t ( i ) ∈ [ 0 , n ] count(i)\in [0,n] count(i)∈[0,n]。
注意 0 ≤ M ≤ 1 0 15 且 0 ≤ A i ≤ 1 0 15 , 0\leq M\leq10^{15}且0 \leq \mathrm{A}_{\mathrm{i}} \leq 10^{15}, 0≤M≤1015且0≤Ai≤1015, for all i。由于 2 49 < 10 … … 15 < 2 50 2^{49}<10……{15}<2^{50} 249<10……15<250,而 2 50 2^{50} 250的二进制表示有51位(注意不是50位,博主就是写成了50位,导致大数据集没有过),所以 i ∈ [ 0 , 50 ] i\in[0,50] i∈[0,50]
要求最大的k,可以用贪心策略,从高位到低位依次枚举,在满足 ( A 1 x o r k ) + ( A 2 x o r k ) + ⋯ + ( A k x o r k ) ≤ M (A_1\ xor\ k)+(A_2\ xor\ k)+\cdots+(A_k\ xor\ k)\leq M (A1 xor k)+(A2 xor k)+⋯+(Ak xor k)≤M的情况下,k当前位取1。
可以提前判断是否存在符合题意的k:即最小化 ( A 1 x o r k ) + ( A 2 x o r k ) + ⋯ + ( A k x o r k ) = ∑ i ≤ 50 ( 1 l l < < i ) ∗ m i n ( n − c o u n t ( i ) , c o u n t ( i ) ) = s u m (A_1\ xor\ k)+(A_2\ xor\ k)+\cdots+(A_k\ xor\ k)=\sum_{i\leq 50}{(1ll<<\ i)* min(n-count(i),count(i))}=sum (A1 xor k)+(A2 xor k)+⋯+(Ak xor k)=∑i≤50(1ll<< i)∗min(n−count(i),count(i))=sum,若 s u m > m sum>m sum>m,则不存在符合题意的k。
复杂度分析
由于 A i A_i Ai二进制表示的位数上界为常数,所以可以认为上述过程是 O ( N ) O(N) O(N) time.
代码
C. Shifts
Solution
解法
设两个保安分别为A和B,总共有n个时间段,每个时间段有3种选择,共有 O ( 3 n ) O(3^n) O(3n)种不同的方案,直接暴力搜索是 O ( 3 n ) O(3^n) O(3n) time,只能过小数据集。直观的想法是对搜索过程进行剪枝(参考该方案),暴力求解的dfs搜索树共有n层,下一层的节点数是上一层节点数的3倍,总共有2种有效的剪枝策略:
- 当搜索到第i层时,当前节点:A和B的开心值均已满足要求,则无需继续搜索,之后的排班方案对结果无影响,res+=pow(3,n-i)
- 当搜索到第i层时,当前节点:之后的每个时间段,A和B均参与工作,开心值总和不满足要求,则无需继续搜索,这里需要提前计算后缀和
官方题解:官方题解是利用meet in the middle来减少搜索空间,整个思路的本质同上,且更优,然而merge的时候需要range tree,本人并不会。。
复杂度分析
O ( 3 n ) O(3^n) O(3n) time.