这次比赛我考了 360 360 360分,第二名,还可以。
可以发现答案为 ∑ i = 1 n + 1 i \begin{aligned}\sum_{i=1}^{n+1}{i}\end{aligned} i=1∑n+1i,时间复杂度为 O ( n ) O(n) O(n),不能过。
用求和公式简化,注:下面的 s s s表示总和, a a a表示首项, b b b表示末项, c c c表示项数。
则 s = ( a + b ) × c 2 s=\frac{(a+b)\times c}{2} s=2(a+b)×c。
那么答案就是 ( n + 1 ) ( n + 2 ) 2 \frac{(n+1)(n+2)}{2} 2(n+1)(n+2),时间复杂度为 O ( 1 ) O(1) O(1)。
注意:一定要开 l o n g l o n g long\:long longlong。
比赛时满分。
找规律,可以发现答案为 2 n + 2 m − 2 2^n+2^m-2 2n+2m−2。
所以直接用高精度做。
比赛时满分。
设 d p i , j dp_{i,j} dpi,j表示 N = i N=i N=i时某种情况的答案,情况如下:
当 j = 0 j=0 j=0,表示所有方向之和;
当 j = 1 j=1 j=1,往上走;
当 j = 2 j=2 j=2,往左走;
当 j = 3 j=3 j=3,往右走。
根据定义,可得 d p i , 0 = d p i , 1 + d p i , 2 + d p i , 3 dp_{i,0}=dp_{i,1}+dp_{i,2}+dp_{i,3} dpi,0=dpi,1+dpi,2+dpi,3。
分三种情况讨论:
继续简化,
d p i , 0 = d p i − 1 , 0 + d p i − 1 , 1 + d p i − 1 , 2 + d p i − 1 , 1 + d p i − 1 , 3 dp_{i,0}=dp_{i-1,0}+dp_{i-1,1}+dp_{i-1,2}+dp_{i-1,1}+dp_{i-1,3} dpi,0=dpi−1,0+dpi−1,1+dpi−1,2+dpi−1,1+dpi−1,3
= d p i − 1 , 0 + ( d p i − 1 , 1 + d p i − 1 , 2 + d p i − 1 , 3 ) + d p i − 1 , 1 \:\:\:\:\:\:\:\:\:\:=dp_{i-1,0}+(dp_{i-1,1}+dp_{i-1,2}+dp_{i-1,3})+dp_{i-1,1} =dpi−1,0+(dpi−1,1+dpi−1,2+dpi−1,3)+dpi−1,1
= d p i − 1 , 0 × 2 + d p i − 1 , 1 \:\:\:\:\:\:\:\:\:\:=dp_{i-1,0}\times2+dp_{i-1,1} =dpi−1,0×2+dpi−1,1
= d p i − 1 , 0 × 2 + d p i − 1 − 1 , 0 \:\:\:\:\:\:\:\:\:\:=dp_{i-1,0}\times2+dp_{i-1-1,0} =dpi−1,0×2+dpi−1−1,0
= d p i − 1 , 0 × 2 + d p i − 2 , 0 \:\:\:\:\:\:\:\:\:\:=dp_{i-1,0}\times2+dp_{i-2,0} =dpi−1,0×2+dpi−2,0
由上式可得:设 f i f_i fi表示当 N = i N=i N=i时的答案,则 f i = f i − 1 × 2 + f i − 2 f_i=f_{i-1}\times2+f_{i-2} fi=fi−1×2+fi−2。
因为有取模运算,所以我们可以边做边取模。
时间复杂度为 O ( n ) O(n) O(n)。
比赛时满分。
可以发现答案就是 ∑ i = 1 n ∑ j = i n ∑ k = i j a k j − i + 1 > A \begin{aligned}\sum_{i=1}^{n}{\sum_{j=i}^{n}{\frac{\sum_{k=i}^{j}{a_k}}{j-i+1}>A}}\end{aligned} i=1∑nj=i∑nj−i+1∑k=ijak>A。
因为除法是乘法的逆运算,所以可将上式转化为 ∑ i = 1 n ∑ j = i n ∑ k = i j a k > ( j − i + 1 ) × A \begin{aligned}\sum_{i=1}^{n}{\sum_{j=i}^{n}{\sum_{k=i}^{j}{a_k}>(j-i+1)\times A}}\end{aligned} i=1∑nj=i∑nk=i∑jak>(j−i+1)×A。
因此可以直接暴力,时间复杂度为 O ( n 3 ) O(n^3) O(n3)。
对算法 1 1 1进行改进,可以发现 ∑ k = i j a k \begin{aligned}\sum_{k=i}^{j}{a_k}\end{aligned} k=i∑jak可以用前缀和来优化。
设 s i s_i si表示 ∑ i = 1 n a i \begin{aligned}\sum_{i=1}^{n}{a_i}\end{aligned} i=1∑nai,则 ∑ k = i j a k \begin{aligned}\sum_{k=i}^{j}{a_k}\end{aligned} k=i∑jak等于 s j − s i − 1 s_j-s_{i-1} sj−si−1。
所以算法 1 1 1的式子可以转化为 ∑ i = 1 n ∑ j = i n s j − s i − 1 > ( j − i + 1 ) × A \begin{aligned}\sum_{i=1}^{n}{\sum_{j=i}^{n}{s_j-s_{i-1}>(j-i+1)\times A}}\end{aligned} i=1∑nj=i∑nsj−si−1>(j−i+1)×A。
我们不用每一次循环求 s i s_i si,而是可以直接递推求得: s i = s i − 1 + a i s_i=s_{i-1}+a_i si=si−1+ai,预处理 s 0 = 0 s_0=0 s0=0。
时间复杂度为 O ( n 2 ) O(n^2) O(n2),可以得 60 60 60分。
换一种思路,注:下面的 s s s与上面的 s s s不同, a a a和 A A A跟上面是一样的。
设 b i = a i − A b_i=a_i-A bi=ai−A, s i = ∑ i = 1 n b i \begin{aligned}s_i=\sum_{i=1}^{n}{b_i}\end{aligned} si=i=1∑nbi,则我们只需要看一下有多少个区间的和大于 0 0 0即可。
也就是 ∑ i = 1 n ∑ j = i n s j − s i − 1 > 0 \begin{aligned}\sum_{i=1}^{n}{\sum_{j=i}^{n}{s_j-s_{i-1}>0}}\end{aligned} i=1∑nj=i∑nsj−si−1>0。
可以用递推预处理出 s i s_i si,可得 s i = s i − 1 + a i − A s_i=s_{i-1}+a_i-A si=si−1+ai−A, s 0 = 0 s_0=0 s0=0。
时间复杂度仍然为 O ( n 2 ) O(n^2) O(n2),但是越来越接近满分算法了。
优化上述方法,可以用树状数组维护区间和。
首先我们将序列离散化,虽然我不是很清楚什么是离散化 。
每一次我们求出 s i s_i si,都看一下 s i s_i si是否大于 0 0 0,如果大于,答案加 1 1 1。
离散化过程如下:
我们先记录每一个的下标(用 c c c表示),初始化 c i = i c_i=i ci=i。
那么我们以 s s s为第一关键字从小到大排序,以 c c c为第二关键字从大到小排序。
那么就得到了一个序列。
接着我们开始用树状数组优化。
每一次我们只用将答案加上 s u m ( c i ) sum(c_i) sum(ci)就行了,并维护—— a d d ( c i ) add(c_i) add(ci)。
下面我讲一讲这些函数的用途:
s u m ( x ) sum(x) sum(x):求出所有以 x x x为根的树状数组的结点的权值总和。
a d d ( x ) add(x) add(x):表示将所有以 x x x为根的树状数组的结点的权值加 1 1 1。
时间复杂度为 O ( n log 2 n ) O(n\log_{2}^{n}) O(nlog2n),可以过。
比赛时 60 60 60分。
改题后满分。