P5170
实际上这个名字很钓鱼啊。
试以 $O(\log n)$ 计算:
$$f( a , b ,c ,n ) = \sum _ { i = 0 } ^ { n } \left \lfloor \dfrac { a i + b } { c } \right \rfloor$$
尝试简化问题:
$$
\begin{aligned}
f ( a , b , c , n ) = & \sum _ { i = 0 } ^ { n } \left \lfloor \dfrac { a i + b } { c } \right \rfloor
\\
= & \sum _ { i = 0 } ^ { n } \left \lfloor \dfrac { (\lfloor a / c \rfloor c + a \bmod c) i + ( \lfloor b / c \rfloor c + b \bmod c ) } { c } \right \rfloor
\\
= & \dfrac { n ( n + 1 )} { 2 } \left\lfloor \dfrac { a } { c } \right\rfloor + ( n + 1 ) \left\lfloor \dfrac { b } { c } \right\rfloor + \sum _ { i = 0 } ^ { n } \left \lfloor \dfrac { ( a \bmod c ) i + ( b \bmod c)} { c } \right \rfloor
\\
= & \dfrac { n ( n + 1 )} { 2 } \left\lfloor \dfrac { a } { c } \right\rfloor + ( n + 1 ) \left\lfloor \dfrac { b } { c } \right\rfloor + f ( a \bmod c , b \bmod c , c , n)
\end{aligned}
$$
这样问题就只要解决 $a , b < c$ 情况的快速求和了。
尝试变换和式:
$$
\begin{aligned}
f( a, b ,c , n) = & \sum _ { i = 0 } ^ { n } \left \lfloor \dfrac { a i + b } { c } \right \rfloor
\\
= & \sum _ { i = 0 } ^ { n } \sum _ { j = 0 } ^ { \lfloor ( a i + b ) / c \rfloor - 1 } 1
\\
= & \sum _ { j = 0 } ^ { \lfloor ( a n + b ) / c \rfloor - 1 } \sum _ { i = 0 } ^ { n } \left[ j < \left \lfloor \dfrac { a i + b } { c } \right \rfloor \right]
\end{aligned}
$$
考虑变换艾弗森括号内的命题。
$$
j < \left \lfloor \dfrac { a i + b } { c } \right \rfloor
$$
该命题等价于:
$$
j + 1 \le \left \lfloor \dfrac { a i + b } { c } \right \rfloor
$$
等价于:
$$
j + 1 \le \dfrac { a i + b } { c }
$$
等价于:
$$
j c + c \le a i + b
$$
等价于:
$$
j c + c - b - 1 < a i
$$
等价于:
$$
i > \left \lfloor \dfrac {j c + c - b - 1 } { a } \right \rfloor
$$
现在考虑代进原式吧,令 $ m = \lfloor ( a n + b ) / c \rfloor$:
$$
\begin{aligned}
f ( a , b , c ,n) = & \sum _ { j = 0 } ^ { m - 1 } \sum _ { i = 0 } ^ { n } \left[ i > \left \lfloor \dfrac {j c + c - b - 1 } { a } \right \rfloor \right]
\\
= & \sum _ { j = 0 } ^ { m - 1 } \left ( n - \left \lfloor \dfrac {j c + c - b - 1 } { a } \right \rfloor \right )
\\
= & nm - f ( c , c - b - 1 , a , m - 1 )
\end{aligned}
$$
先取模再递归,非常像欧几里得算法,也容易发现该算法的复杂度是 $ O (\log n ) $ 的。
上面是最简单的一个问题。
下面是两个变种:
$$ g ( a , b ,c , n) = \sum _ { i = 0 } ^ { n } i \left \lfloor \dfrac { a i + b } { c } \right \rfloor$$
$$ h ( a , b ,c , n) = \sum _ { i = 0 } ^ { n } \left \lfloor \dfrac { a i + b } { c } \right \rfloor ^ 2 $$
对于函数 $g$:
$$
\begin{aligned}
g ( a , b ,c ,n) = & g ( a \bmod c, b \bmod c , c ,n)
\\
& + \dfrac { n ( n + 1 ) ( 2 n + 1 ) } { 6 } \left\lfloor \dfrac{ a } { c } \right \rfloor + \dfrac { n ( n + 1 ) } { 2 } \left \lfloor \dfrac { b } { c } \right \rfloor
\end{aligned}
$$
只需要考虑 $a, b < c$ 的情况。令 $ m = \lfloor ( a n + b ) / c \rfloor$:
$$
\begin{aligned}
g ( a, b , c ,n ) = & \sum _ { i = 0 } ^ { n } i \left \lfloor \dfrac { a i + b } { c } \right \rfloor
\\
= & \sum _ { j = 0 } ^ { m - 1 } \sum _ { i = 0 } ^ { n } \left[ j < \left \lfloor \dfrac { a i + b } { c } \right \rfloor \right] i
\end{aligned}
$$
设 $t = \lfloor ( j c + c - b - 1 ) / a \rfloor$,我们能得到:
$$
\begin{aligned}
g ( a , b , c , n ) = & \sum _ { j = 0 } ^ { m - 1 } \sum _ { i = 0 } ^ { n } [ i > t ] i
\\
= & \sum _ { j = 0 } ^ { m - 1 } \dfrac { ( t + n + 1 ) ( n - t ) } { 2 }
\\
= & \dfrac { 1 } { 2 } \left ( m n ( n + 1 ) - \sum _ { j = 0 } ^ { m - 1 } t ^ 2 - \sum _ { j = 0 }^ { m - 1 } t \right )
\\
= & \dfrac { 1 } { 2 } \left ( m n ( n + 1 ) - h ( c , c - b - 1 , a , m - 1 ) - f ( c , c - b -1 , a , m - 1 ) \right )
\end{aligned}
$$
对于函数 $h$:
$$
\begin{aligned}
h (a ,b , c ,n) = & h ( a \bmod c, b \bmod c, c ,n)
\\
& + 2 \left \lfloor \dfrac{ b } { c } \right \rfloor f( a \bmod c, b \bmod c, c ,n) + 2 \left \lfloor \dfrac{ a } { c } \right \rfloor g( a \bmod c, b \bmod c, c ,n)
\\
& + \left \lfloor \dfrac { a } { c } \right \rfloor ^ 2 \dfrac { n ( n + 1 ) ( 2 n + 1 ) } { 6 } + \left \lfloor \dfrac { b } { c } \right \rfloor ^ 2 ( n + 1 ) + \left \lfloor \dfrac { a } { c } \right \rfloor \left \lfloor \dfrac { b } { c } \right \rfloor n ( n + 1 )
\end{aligned}
$$
现在也只需要考虑 $a , b < c$ 的情况了。
同样,我们设 $ m = \lfloor ( a n + b ) / c \rfloor$,$ t = \lfloor ( j c + c - b - 1 ) / a \rfloor$。
然后我们换一种平方的处理方式:
$$
n ^ 2 = 2 \dfrac { n ( n + 1 ) } { 2 } - n = \left( 2 \sum _ { i = 1 } ^ { n } i \right) - n
$$
于是就有:
$$
\begin{aligned}
h ( a, b, c, n ) = & \sum _ { i = 0 } ^ { n } \left\lfloor \dfrac {a i + b } { c } \right\rfloor ^ 2
\\
= & \sum _ { i = 0 } ^ { n } \left[ \left ( 2 \sum _ { j = 1 } ^ { \lfloor ( a i + b ) / c \rfloor} j\right ) - \left \lfloor \dfrac { a i + b } { c } \right \rfloor\right]
\\
= & \left( 2 \sum _ { i = 0 } ^ { n } \sum _ { j = 1 } ^ { \lfloor ( a i + b) / c \rfloor} j\right) - f ( a , b , c , n )
\\
= & \left( 2 \sum _ { i = 0 } ^ { n } \sum _ { j = 0 } ^ { \lfloor ( a i + b) / c \rfloor - 1 } ( j + 1 )\right) - f ( a , b , c , n )
\\
= & \left( 2 \sum _ { j = 0 } ^ { m - 1 } ( j + 1 ) \sum _ { i = 0 } ^ { n } \left[ j < \left \lfloor \dfrac {a i + b} { c } \right\rfloor \right] \right) - f ( a , b , c , n )
\\
= & \left( 2 \sum _ { j = 0 } ^ { m - 1 } ( j + 1 ) \sum _ { i = 0 } ^ { n } \left[ i > t \right] \right) - f ( a , b , c , n )
\\
= & \left( 2 \sum _ { j = 0 } ^ { m - 1 } ( j + 1 ) ( n - t ) \right) - f ( a , b , c , n )
\\
= & \left ( n m ( m +1 ) - 2 \sum _ { j = 0 } ^ { m - 1 } ( j + 1 ) \left\lfloor \dfrac {j c + c - b - 1 } { a } \right\rfloor \right ) - f( a ,b, c , n)
\\
= & n m ( m +1 ) - 2 g ( c, c - b - 1 ,a ,m -1 )
\\
& - 2 f ( c, c - b - 1 , a , m - 1 ) - f( a ,b, c , n)
\end{aligned}
$$
具体实现的时候采用整体递归。
代码:
1 |
|