几个等式
其中
⌊
⌋
\lfloor \rfloor
⌊ ⌋ 表示向下取整,
⌈
⌉
\lceil \rceil
⌈ ⌉ 表示向上取整。
a
≤
⌊
b
c
⌋
⇔
a
⋅
c
≤
b
a \le \lfloor { b \over c } \rfloor \Leftrightarrow a \cdot c \le b
a ≤ ⌊ c b ⌋ ⇔ a ⋅ c ≤ b
a
<
⌈
b
c
⌉
⇔
a
⋅
c
<
b
a \lt \lceil { b \over c } \rceil \Leftrightarrow a \cdot c \lt b
a < ⌈ c b ⌉ ⇔ a ⋅ c < b
a
≥
⌈
b
c
⌉
⇔
a
⋅
c
≥
b
a \ge \lceil { b \over c } \rceil \Leftrightarrow a \cdot c \ge b
a ≥ ⌈ c b ⌉ ⇔ a ⋅ c ≥ b
a
>
⌊
b
c
⌋
⇔
a
⋅
c
>
b
a \gt \lfloor { b \over c } \rfloor \Leftrightarrow a \cdot c \gt b
a > ⌊ c b ⌋ ⇔ a ⋅ c > b 上面四个式子可以这么理解:趋近可能取等,趋远不可能取等。
⌈
b
c
⌉
⇔
⌊
b
+
c
−
1
c
⌋
\lceil{ b \over c } \rceil \Leftrightarrow \lfloor{ b + c - 1 \over c } \rfloor
⌈ c b ⌉ ⇔ ⌊ c b + c − 1 ⌋
⌊
b
c
⌋
⇔
⌈
b
−
c
+
1
c
⌉
\lfloor{ b \over c } \rfloor \Leftrightarrow \lceil{ b - c + 1 \over c } \rceil
⌊ c b ⌋ ⇔ ⌈ c b − c + 1 ⌉ 注:本篇博客若在算式中出现不等式,则该不等式表示为若成立值为一,若不成立值为零。
类欧几里得算法的简介
它本质上是一个函数,算法是用于快速求下面三个式子的值:
f
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
⌊
a
⋅
i
+
b
c
⌋
f(a,b,c,n) = \sum_{i=0}^n \lfloor{ a \cdot i + b \over c }\rfloor
f ( a , b , c , n ) = i = 0 ∑ n ⌊ c a ⋅ i + b ⌋
g
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
i
⋅
⌊
a
⋅
i
+
b
c
⌋
g(a,b,c,n) = \sum_{i=0}^n i \cdot \lfloor{ a \cdot i + b \over c }\rfloor
g ( a , b , c , n ) = i = 0 ∑ n i ⋅ ⌊ c a ⋅ i + b ⌋
h
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
⌊
a
⋅
i
+
b
c
⌋
2
h(a,b,c,n) = \sum_{i=0}^n \lfloor{ a \cdot i + b \over c }\rfloor^2
h ( a , b , c , n ) = i = 0 ∑ n ⌊ c a ⋅ i + b ⌋ 2 由于求解过程与求解GCD一样涉及取模操作,因而时间复杂度相似,所以叫做类欧几里得算法。
求解f
f
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
⌊
a
⋅
i
+
b
c
⌋
f(a,b,c,n) = \sum_{i=0}^n \lfloor{ a \cdot i + b \over c }\rfloor
f ( a , b , c , n ) = i = 0 ∑ n ⌊ c a ⋅ i + b ⌋ 分类讨论 : 1.
a
=
0
a = 0
a = 0 , 此时返回
(
n
+
1
)
⋅
⌊
b
c
⌋
(n + 1) \cdot \lfloor {b \over c}\rfloor
( n + 1 ) ⋅ ⌊ c b ⌋ ,以下情况
a
a
a 均大于零(g,h同理)。 2.
a
≥
c
a \ge c
a ≥ c 或
b
≥
c
b \ge c
b ≥ c 把
⌊
a
⋅
i
+
b
c
⌋
\lfloor{ a \cdot i + b \over c }\rfloor
⌊ c a ⋅ i + b ⌋ 拆开,变成
⌊
(
a
%
c
)
⋅
i
+
b
%
c
c
⌋
\lfloor{ ( a \% c) \cdot i + b \% c \over c }\rfloor
⌊ c ( a % c ) ⋅ i + b % c ⌋ +
⌊
a
c
⌋
⋅
i
\lfloor{a \over c} \rfloor \cdot i
⌊ c a ⌋ ⋅ i +
⌊
b
c
⌋
\lfloor{ b \over c} \rfloor
⌊ c b ⌋ 则
f
(
a
,
b
,
c
,
n
)
⇔
f
(
a
%
c
,
b
%
c
,
c
,
n
)
+
n
⋅
(
n
+
1
)
2
⋅
⌊
a
c
⌋
+
(
n
+
1
)
⋅
⌊
b
c
⌋
f(a , b , c , n ) \Leftrightarrow f( a\%c,b\%c,c,n ) + { n \cdot ( n + 1 )\over 2} \cdot \lfloor{a \over c} \rfloor + (n + 1) \cdot \lfloor{ b \over c} \rfloor
f ( a , b , c , n ) ⇔ f ( a % c , b % c , c , n ) + 2 n ⋅ ( n + 1 ) ⋅ ⌊ c a ⌋ + ( n + 1 ) ⋅ ⌊ c b ⌋ 3.
a
<
c
a < c
a < c 且
b
<
c
b < c
b < c 设
m
=
⌊
a
⋅
n
+
b
c
⌋
m = \lfloor { a \cdot n + b \over c } \rfloor
m = ⌊ c a ⋅ n + b ⌋ 则
f
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
⌊
a
⋅
i
+
b
c
⌋
f(a,b,c,n) = \sum_{i=0}^n \lfloor{ a \cdot i + b \over c }\rfloor
f ( a , b , c , n ) = i = 0 ∑ n ⌊ c a ⋅ i + b ⌋ 转化为
f
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
∑
j
=
1
m
[
⌊
a
⋅
i
+
b
c
⌋
≥
j
]
f(a,b,c,n) = \sum_{i = 0}^n\sum_{j = 1}^m[\lfloor{ a \cdot i + b \over c} \rfloor \ge j]
f ( a , b , c , n ) = i = 0 ∑ n j = 1 ∑ m [ ⌊ c a ⋅ i + b ⌋ ≥ j ] 这个在几何上,可以理解为引一条直线
y
=
a
⋅
x
+
b
c
y = { a \cdot x + b \over c}
y = c a ⋅ x + b ,它与平面直角坐标系和
y
=
n
y = n
y = n 围成的直角梯形(也可能是直角三角形)内整点的数量(包括
y
y
y 轴上的点,但不含
x
x
x 轴上的点以及原点)。
其实
y
y
y 轴上没有整点,因为当
a
<
c
a < c
a < c 且
b
<
c
b < c
b < c 时
y
y
y 轴上不会有整点。 好像扯开了-_-||,继续向下推,此时我们将求和符号上的参数做一些小小的变动,达到改变数值但次数不变的目的(其实是将
j
j
j 改变范围的起止点但不改变范围大小):
f
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
∑
j
=
0
m
−
1
[
⌊
a
⋅
i
+
b
c
⌋
≥
j
+
1
]
f(a,b,c,n) = \sum_{i = 0}^n\sum_{j = 0}^{m -1}[\lfloor{ a \cdot i + b \over c} \rfloor \ge j + 1]
f ( a , b , c , n ) = i = 0 ∑ n j = 0 ∑ m − 1 [ ⌊ c a ⋅ i + b ⌋ ≥ j + 1 ] 去掉分母
f
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
∑
j
=
0
m
−
1
[
a
⋅
i
≥
j
⋅
c
+
c
−
b
]
f(a,b,c,n) = \sum_{i = 0}^n\sum_{j = 0}^{m -1}[a \cdot i \ge j \cdot c + c - b]
f ( a , b , c , n ) = i = 0 ∑ n j = 0 ∑ m − 1 [ a ⋅ i ≥ j ⋅ c + c − b ] 去等
f
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
∑
j
=
0
m
−
1
[
a
⋅
i
>
j
⋅
c
+
c
−
b
−
1
]
f(a,b,c,n) = \sum_{i = 0}^n\sum_{j = 0}^{m -1}[a \cdot i \gt j \cdot c + c - b - 1]
f ( a , b , c , n ) = i = 0 ∑ n j = 0 ∑ m − 1 [ a ⋅ i > j ⋅ c + c − b − 1 ] 两边同时除掉a
f
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
∑
j
=
0
m
−
1
[
i
>
j
⋅
c
+
c
−
b
−
1
a
]
f(a,b,c,n) = \sum_{i = 0}^n\sum_{j = 0}^{m -1}[i \gt { j \cdot c + c - b - 1 \over a }]
f ( a , b , c , n ) = i = 0 ∑ n j = 0 ∑ m − 1 [ i > a j ⋅ c + c − b − 1 ] 两个sigma符号可交换位置(严谨的数学证明我不会,但是脑补一下码两个for循环时,交换两个互不影响(起止点独立)的两个for循环时,不影响结果)。交换后再用
∑
i
=
0
n
\sum_{i = 0}^n
∑ i = 0 n 把
i
i
i 吞掉(对于任意的
j
j
j ,若使式子值为真,
i
i
i 至少为
⌊
j
⋅
c
+
c
−
b
−
1
a
⌋
+
1
\lfloor { j \cdot c + c - b - 1 \over a } \rfloor + 1
⌊ a j ⋅ c + c − b − 1 ⌋ + 1 ,凭借这个思想可得到下面的式子,也可以用整点法)。
f
(
a
,
b
,
c
,
n
)
=
∑
j
=
0
m
−
1
(
n
−
⌊
j
⋅
c
+
c
−
b
−
1
a
⌋
)
f(a,b,c,n) = \sum_{j = 0}^{m -1}(n - \lfloor { j \cdot c + c - b - 1 \over a } \rfloor)
f ( a , b , c , n ) = j = 0 ∑ m − 1 ( n − ⌊ a j ⋅ c + c − b − 1 ⌋ ) 观察到括号里面是
m
m
m 个
n
n
n 和一个f形式的求和,得到:
f
(
a
,
b
,
c
,
n
)
=
n
⋅
m
−
f
(
c
,
c
−
b
−
1
,
a
,
m
−
1
)
f(a,b,c,n) = n \cdot m - f( c , c - b - 1 , a , m - 1 )
f ( a , b , c , n ) = n ⋅ m − f ( c , c − b − 1 , a , m − 1 ) 此时第1,3个系数从
(
a
,
c
)
(a , c)
( a , c ) 变成
(
c
,
a
%
c
)
(c , a \% c)
( c , a % c ) ,由以上三式可证,这一过程与欧几里得求GCD复杂度相似。
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
inline ll f ( ll a , ll b , ll c , ll n ) {
if ( ! a ) {
return ( n + 1 ) * ( b / c ) ;
}
if ( a > c || b > c ) {
return ( n * ( n + 1 ) / 2 ) * ( a / c ) + ( n + 1 ) * ( b / c ) + f ( a % c , b % c , c , n ) ;
}
ll m = ( a * n + b ) / c;
return n * m - f ( c , c - b - 1 , a , m - 1 ) ;
}
int main ( ) {
ll a , b , c , n;
scanf ( "%lld%lld%lld%lld" , & a, & b, & c, & n) ;
printf ( "%lld" , f ( a , b , c , n ) ) ;
return 0 ;
}
这里说明一下,g , h的推导都要用到f,g,h,下面两个要一口气学完。
求解g
首先,我们要求证(可能有大佬嫌我啰嗦了,可本蒟蒻就是不会 )
∑
i
=
0
n
i
2
=
n
⋅
(
n
+
1
)
⋅
(
2
n
+
1
)
6
\sum_{i=0}^n i^2 = \frac{n \cdot(n+1)\cdot(2n+1)}{6}
i = 0 ∑ n i 2 = 6 n ⋅ ( n + 1 ) ⋅ ( 2 n + 1 ) 首先,根据式子
(
n
+
1
)
3
=
n
3
+
3
⋅
n
2
+
3
⋅
n
+
1
(n + 1) ^ 3 = n ^ 3 + 3 \cdot n^2+3 \cdot n + 1
( n + 1 ) 3 = n 3 + 3 ⋅ n 2 + 3 ⋅ n + 1 得出:
(
n
+
1
)
3
−
n
3
=
3
⋅
n
2
+
3
⋅
n
+
1
(n + 1) ^ 3 - n ^ 3 = 3 \cdot n ^ 2 + 3 \cdot n + 1
( n + 1 ) 3 − n 3 = 3 ⋅ n 2 + 3 ⋅ n + 1 以此类推:
n
3
−
(
n
−
1
)
3
=
3
⋅
(
n
−
1
)
2
+
3
⋅
(
n
−
1
)
+
1
n ^ 3 - (n - 1) ^ 3 = 3 \cdot (n - 1) ^ 2 + 3 \cdot (n - 1) + 1
n 3 − ( n − 1 ) 3 = 3 ⋅ ( n − 1 ) 2 + 3 ⋅ ( n − 1 ) + 1
…
…
…
…
…
…
…
…
…
…
…
…
…
…
……………………………………
… … … … … … … … … … … … … …
3
3
−
2
3
=
3
⋅
2
2
+
3
⋅
2
+
1
3 ^ 3 - 2 ^ 3 = 3 \cdot 2 ^ 2 + 3 \cdot 2 + 1
3 3 − 2 3 = 3 ⋅ 2 2 + 3 ⋅ 2 + 1
2
3
−
1
3
=
3
⋅
1
2
+
3
⋅
1
+
1
2 ^ 3 - 1 ^ 3 = 3 \cdot 1 ^ 2 + 3 \cdot 1 + 1
2 3 − 1 3 = 3 ⋅ 1 2 + 3 ⋅ 1 + 1 将上式左右两边相加得(为了方便,只加到
(
n
−
1
)
3
(n - 1)^3
( n − 1 ) 3 ):
(
n
−
1
)
3
−
1
=
3
⋅
(
∑
i
=
0
n
i
2
)
+
3
∗
(
∑
i
=
0
n
i
)
+
n
(n - 1) ^ 3 - 1 = 3 \cdot ( \sum_{i=0}^n i^2 ) + 3 * ( \sum_{i=0}^n i) + n
( n − 1 ) 3 − 1 = 3 ⋅ ( i = 0 ∑ n i 2 ) + 3 ∗ ( i = 0 ∑ n i ) + n 因为
∑
i
=
0
n
i
=
n
⋅
(
n
+
1
)
2
\sum_{i=0}^n i = { n \cdot (n + 1) \over 2 }
i = 0 ∑ n i = 2 n ⋅ ( n + 1 ) 得出
3
∗
∑
i
=
0
n
i
2
+
3
⋅
(
n
+
1
)
⋅
n
2
+
n
=
n
3
+
3
⋅
n
2
+
3
⋅
n
3 * \sum_{i=0}^n i^2 + { 3 \cdot ( n + 1) \cdot n \over 2} + n= n^3 + 3 \cdot n ^ 2 + 3 \cdot n
3 ∗ i = 0 ∑ n i 2 + 2 3 ⋅ ( n + 1 ) ⋅ n + n = n 3 + 3 ⋅ n 2 + 3 ⋅ n 一口气推完后,就得到
∑
i
=
0
n
i
2
=
n
⋅
(
n
+
1
)
⋅
(
2
n
+
1
)
6
\sum_{i=0}^n i^2 = \frac{n \cdot(n+1)\cdot(2n+1)}{6}
i = 0 ∑ n i 2 = 6 n ⋅ ( n + 1 ) ⋅ ( 2 n + 1 ) 下面开始推
g
g
g 了
g
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
i
⋅
⌊
a
⋅
i
+
b
c
⌋
g(a,b,c,n) = \sum_{i=0}^n i \cdot \lfloor{ a \cdot i + b \over c }\rfloor
g ( a , b , c , n ) = i = 0 ∑ n i ⋅ ⌊ c a ⋅ i + b ⌋ 再次分类讨论 1.
a
=
0
a = 0
a = 0 时,到达边界,返回
n
⋅
(
n
+
1
)
2
⋅
⌊
b
c
⌋
{ n \cdot (n + 1) \over 2} \cdot \lfloor{b \over c} \rfloor
2 n ⋅ ( n + 1 ) ⋅ ⌊ c b ⌋ 2. 当
a
≥
c
a \ge c
a ≥ c 或
b
≥
c
b \ge c
b ≥ c 的情况,套上上面证的平方和公式,可得:
g
(
a
,
b
,
c
,
n
)
=
g
(
a
%
c
,
b
%
c
,
c
,
n
)
+
n
⋅
(
n
+
1
)
⋅
(
2
⋅
n
+
1
)
6
∗
⌊
a
c
⌋
+
n
⋅
(
n
+
1
)
2
∗
⌊
b
c
⌋
g(a,b,c,n) = g(a \% c ,b \% c,c,n) + { n \cdot (n + 1) \cdot (2 \cdot n + 1) \over 6} * \lfloor{ a \over c }\rfloor + { n \cdot (n + 1) \over 2 } * \lfloor{ b \over c }\rfloor
g ( a , b , c , n ) = g ( a % c , b % c , c , n ) + 6 n ⋅ ( n + 1 ) ⋅ ( 2 ⋅ n + 1 ) ∗ ⌊ c a ⌋ + 2 n ⋅ ( n + 1 ) ∗ ⌊ c b ⌋ 3. 当
a
<
c
a < c
a < c 且
b
<
c
b < c
b < c 时,根据
f
f
f 的思路,可以得到:
g
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
i
⋅
∑
j
=
1
m
[
⌊
a
⋅
i
+
b
c
⌋
≥
j
]
g(a , b , c , n) = \sum_{i=0}^n i \cdot \sum_{j=1}^m[ \lfloor { a \cdot i + b \over c } \rfloor \ge j ]
g ( a , b , c , n ) = i = 0 ∑ n i ⋅ j = 1 ∑ m [ ⌊ c a ⋅ i + b ⌋ ≥ j ]
m
=
⌊
a
⋅
n
+
b
c
⌋
m = \lfloor { a \cdot n + b \over c } \rfloor
m = ⌊ c a ⋅ n + b ⌋ (怕忘了 ) 跳步得(手动滑稽 ):
g
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
i
⋅
∑
j
=
0
m
−
1
[
i
>
j
⋅
c
+
c
−
b
−
1
a
]
g(a , b , c , n) = \sum_{i=0}^n i \cdot \sum_{j=0}^{m - 1}[ i \gt { j \cdot c + c - b - 1 \over a } ]
g ( a , b , c , n ) = i = 0 ∑ n i ⋅ j = 0 ∑ m − 1 [ i > a j ⋅ c + c − b − 1 ] (不懂的请看回
f
f
f ) 根据求
f
f
f 时用到的整点思想,对于任意的
f
f
f ,为了使表达式为真,
i
i
i 至少为
⌊
j
⋅
c
+
c
−
b
−
1
a
⌋
+
1
\lfloor { j \cdot c + c - b - 1 \over a }\rfloor + 1
⌊ a j ⋅ c + c − b − 1 ⌋ + 1 ,其实这个上面已讲过了 。 设
t
=
⌊
j
⋅
c
+
c
−
b
−
1
a
⌋
t = \lfloor { j \cdot c + c - b - 1 \over a }\rfloor
t = ⌊ a j ⋅ c + c − b − 1 ⌋
g
(
a
,
b
,
c
,
n
)
=
∑
j
=
0
m
−
1
∑
i
=
t
+
1
n
i
g(a , b , c , n) =\sum_{j=0}^{m - 1} \sum_{i=t + 1}^n i
g ( a , b , c , n ) = j = 0 ∑ m − 1 i = t + 1 ∑ n i 不难发现这其实是一个等差数列
s
n
′
=
(
a
1
+
a
n
′
)
⋅
n
′
2
s_{n'} = { (a_1 + a_{n'}) \cdot n' \over 2 }
s n ′ = 2 ( a 1 + a n ′ ) ⋅ n ′
g
(
a
,
b
,
c
,
n
)
=
∑
j
=
0
m
−
1
(
t
+
1
+
n
)
⋅
(
n
−
t
)
2
g(a , b , c , n) =\sum_{j=0}^{m - 1} { (t + 1 + n) \cdot (n - t) \over 2}
g ( a , b , c , n ) = j = 0 ∑ m − 1 2 ( t + 1 + n ) ⋅ ( n − t )
a
1
a_1
a 1 对应
t
+
1
t + 1
t + 1 ,
a
n
′
a_{n'}
a n ′ 对应
n
n
n ,
n
′
n'
n ′ 对应
(
n
−
t
)
(n - t)
( n − t ) 。 继续推
g
(
a
,
b
,
c
,
n
)
=
n
⋅
m
⋅
(
1
+
n
)
2
−
∑
j
=
0
m
−
1
t
2
−
∑
j
=
0
m
−
1
t
2
2
g(a , b , c , n) = { n \cdot m \cdot (1 + n) \over 2 } - \sum_{j=0}^{m - 1}{t \over2 } - \sum_{j=0}^{m - 1}{t ^ 2 \over 2}
g ( a , b , c , n ) = 2 n ⋅ m ⋅ ( 1 + n ) − j = 0 ∑ m − 1 2 t − j = 0 ∑ m − 1 2 t 2 恢复
t
t
t 的真面目可得:
g
(
a
,
b
,
c
,
n
)
=
n
⋅
m
⋅
(
1
+
n
)
2
−
1
2
⋅
h
(
c
,
c
−
b
−
1
,
a
,
m
−
1
)
−
1
2
⋅
f
(
c
,
c
−
b
−
1
,
a
,
m
−
1
)
g(a , b , c , n) = { n \cdot m \cdot (1 + n) \over 2 } - { 1 \over 2 } \cdot h( c , c - b - 1 , a , m - 1 ) - { 1 \over 2 } \cdot f(c , c - b - 1 , a , m - 1)
g ( a , b , c , n ) = 2 n ⋅ m ⋅ ( 1 + n ) − 2 1 ⋅ h ( c , c − b − 1 , a , m − 1 ) − 2 1 ⋅ f ( c , c − b − 1 , a , m − 1 ) 这里要用到
h
h
h ,所以我们继续推吧。
求解h
h
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
⌊
a
⋅
i
+
b
c
⌋
2
h(a,b,c,n) = \sum_{i=0}^n \lfloor{ a \cdot i + b \over c }\rfloor^2
h ( a , b , c , n ) = i = 0 ∑ n ⌊ c a ⋅ i + b ⌋ 2 还是分类讨论 1.
a
=
0
a = 0
a = 0 时,边界,返回
(
n
+
1
)
⋅
⌊
b
c
⌋
2
(n + 1) \cdot \lfloor { b\over c}\rfloor ^2
( n + 1 ) ⋅ ⌊ c b ⌋ 2 2. 若
a
≥
c
a \ge c
a ≥ c 或
b
≥
c
b \ge c
b ≥ c ,通过取模,不难得到
h
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
⌊
a
⋅
i
+
b
c
⌋
2
=
∑
i
=
0
n
[
⌊
a
c
⌋
∗
i
+
⌊
b
c
⌋
+
(
a
%
c
c
∗
i
+
b
%
c
c
)
]
2
h(a,b,c,n) = \sum_{i=0}^n \lfloor{ a \cdot i + b \over c }\rfloor^2 = \sum_{i=0}^n [\lfloor { a \over c }\rfloor * i + \lfloor { b \over c } \rfloor + ({a \% c \over c} * i + { b \% c \over c }) ]^2
h ( a , b , c , n ) = i = 0 ∑ n ⌊ c a ⋅ i + b ⌋ 2 = i = 0 ∑ n [ ⌊ c a ⌋ ∗ i + ⌊ c b ⌋ + ( c a % c ∗ i + c b % c ) ] 2 这个式子比较复杂,先写一个简单的对应一下
(
x
+
y
+
z
)
2
=
x
2
+
y
2
+
z
2
+
2
⋅
x
⋅
y
+
2
⋅
x
⋅
z
+
2
⋅
y
⋅
z
(x + y + z)^2 = x^2 + y^2 + z^2 + 2 \cdot x \cdot y + 2 \cdot x \cdot z + 2 \cdot y \cdot z
( x + y + z ) 2 = x 2 + y 2 + z 2 + 2 ⋅ x ⋅ y + 2 ⋅ x ⋅ z + 2 ⋅ y ⋅ z ,用一一对应法,可得出上面的展开式为:
h
(
a
,
b
,
c
,
n
)
=
h
(
a
%
c
,
b
%
c
,
c
,
n
)
+
n
⋅
(
n
+
1
)
⋅
(
2
⋅
n
+
1
)
6
⋅
⌊
a
c
⌋
2
+
(
n
+
1
)
⋅
⌊
b
c
⌋
2
+
2
⋅
⌊
b
c
⌋
⋅
f
(
a
%
c
,
b
%
c
,
c
,
n
)
+
2
⋅
⌊
a
c
⌋
⋅
g
(
a
%
c
,
b
%
c
,
c
,
n
)
+
⌊
a
c
⌋
⋅
⌊
b
c
⌋
⋅
n
⋅
(
n
+
1
)
h(a,b,c,n) = h(a \%c,b \% c,c,n) + {n \cdot ( n + 1 ) \cdot (2 \cdot n + 1) \over 6} \cdot \lfloor { a \over c }\rfloor^2 + (n + 1) \cdot \lfloor { b \over c }\rfloor^2 \\ + 2 \cdot \lfloor { b \over c }\rfloor \cdot f(a \%c,b \% c,c,n) + 2 \cdot \lfloor {a \over c} \rfloor \cdot g(a \%c,b \% c,c,n) + \lfloor {a \over c} \rfloor \cdot \lfloor {b \over c} \rfloor \cdot n \cdot (n + 1)
h ( a , b , c , n ) = h ( a % c , b % c , c , n ) + 6 n ⋅ ( n + 1 ) ⋅ ( 2 ⋅ n + 1 ) ⋅ ⌊ c a ⌋ 2 + ( n + 1 ) ⋅ ⌊ c b ⌋ 2 + 2 ⋅ ⌊ c b ⌋ ⋅ f ( a % c , b % c , c , n ) + 2 ⋅ ⌊ c a ⌋ ⋅ g ( a % c , b % c , c , n ) + ⌊ c a ⌋ ⋅ ⌊ c b ⌋ ⋅ n ⋅ ( n + 1 ) 3. 若
a
<
c
a \lt c
a < c 且
b
<
c
b \lt c
b < c 时, 考虑把狰狞的
x
2
x^2
x 2 拆一下,可得:
x
2
=
2
⋅
x
⋅
(
x
+
1
)
2
−
x
=
2
⋅
∑
i
=
0
x
i
−
x
x^2 = 2 \cdot {x \cdot ( x + 1 ) \over 2} - x = 2 \cdot \sum_{i = 0}^x i - x
x 2 = 2 ⋅ 2 x ⋅ ( x + 1 ) − x = 2 ⋅ i = 0 ∑ x i − x 利用这个拆开原式,并设
m
=
⌊
a
⋅
n
+
b
c
⌋
m = \lfloor {a \cdot n + b \over c} \rfloor
m = ⌊ c a ⋅ n + b ⌋ ,可得:
h
(
a
,
b
,
c
,
n
)
=
∑
i
=
0
n
(
(
2
⋅
∑
j
=
1
⌊
a
⋅
i
+
b
c
⌋
j
)
−
⌊
a
⋅
i
+
b
c
⌋
)
h(a,b,c,n) =\sum_{i = 0}^n ((2 \cdot \sum_{j = 1}^{ \lfloor {a \cdot i + b \over c}\rfloor} j) - \lfloor {a \cdot i + b \over c} \rfloor )
h ( a , b , c , n ) = i = 0 ∑ n ( ( 2 ⋅ j = 1 ∑ ⌊ c a ⋅ i + b ⌋ j ) − ⌊ c a ⋅ i + b ⌋ ) 把
2
⋅
∑
j
=
1
⌊
a
⋅
i
+
b
c
⌋
j
2 \cdot \sum_{j = 1}^{ \lfloor {a \cdot i + b \over c}\rfloor} j
2 ⋅ ∑ j = 1 ⌊ c a ⋅ i + b ⌋ j 和
⌊
a
⋅
i
+
b
c
⌋
\lfloor {a \cdot i + b \over c} \rfloor
⌊ c a ⋅ i + b ⌋ 拆开得(思想参考求
f
f
f 时用的数形结合思想,上式是一列一列地统计整点,下式是一行一行地统计整点):
h
(
a
,
b
,
c
,
n
)
=
2
⋅
(
∑
j
=
0
m
−
1
(
j
+
1
)
⋅
∑
i
=
0
n
[
⌊
a
⋅
i
+
b
c
⌋
≥
j
+
1
]
)
−
f
(
a
,
b
,
c
,
n
)
h(a,b,c,n) = 2 \cdot( \sum_{j = 0}^{m - 1} (j + 1) \cdot \sum_{i = 0}^n [\lfloor {a \cdot i + b \over c} \rfloor \ge j + 1 ] ) - f(a , b , c , n )
h ( a , b , c , n ) = 2 ⋅ ( j = 0 ∑ m − 1 ( j + 1 ) ⋅ i = 0 ∑ n [ ⌊ c a ⋅ i + b ⌋ ≥ j + 1 ] ) − f ( a , b , c , n )
h
(
a
,
b
,
c
,
n
)
=
2
⋅
(
∑
j
=
0
m
−
1
j
⋅
∑
i
=
0
n
[
⌊
a
⋅
i
+
b
c
⌋
≥
j
+
1
]
)
+
2
⋅
(
∑
j
=
0
m
−
1
∑
i
=
0
n
[
⌊
a
⋅
i
+
b
c
⌋
≥
j
+
1
]
)
−
f
(
a
,
b
,
c
,
n
)
h(a,b,c,n) = 2 \cdot( \sum_{j = 0}^{m - 1} j \cdot \sum_{i = 0}^n [\lfloor {a \cdot i + b \over c} \rfloor \ge j + 1 ] ) \\ + 2 \cdot( \sum_{j = 0}^{m - 1}\sum_{i = 0}^n [\lfloor {a \cdot i + b \over c} \rfloor \ge j + 1 ] ) - f(a , b , c , n )
h ( a , b , c , n ) = 2 ⋅ ( j = 0 ∑ m − 1 j ⋅ i = 0 ∑ n [ ⌊ c a ⋅ i + b ⌋ ≥ j + 1 ] ) + 2 ⋅ ( j = 0 ∑ m − 1 i = 0 ∑ n [ ⌊ c a ⋅ i + b ⌋ ≥ j + 1 ] ) − f ( a , b , c , n ) 参照求
f
f
f 的思路,跳步得o( ̄︶ ̄ )o
h
(
a
,
b
,
c
,
n
)
=
2
⋅
(
∑
j
=
0
m
−
1
j
⋅
∑
i
=
0
n
[
i
>
⌊
j
⋅
c
−
c
−
b
−
1
a
⌋
]
)
+
2
⋅
(
∑
j
=
0
m
−
1
∑
i
=
0
n
[
i
>
⌊
j
⋅
c
−
c
−
b
−
1
a
⌋
]
)
−
f
(
a
,
b
,
c
,
n
)
h(a,b,c,n) = 2 \cdot( \sum_{j = 0}^{m - 1} j \cdot \sum_{i = 0}^n [i \gt \lfloor { j \cdot c - c - b - 1 \over a} \rfloor ] ) \\ + 2 \cdot( \sum_{j = 0}^{m - 1}\sum_{i = 0}^n [i \gt \lfloor { j \cdot c - c - b - 1 \over a} \rfloor ] ) - f(a , b , c , n )
h ( a , b , c , n ) = 2 ⋅ ( j = 0 ∑ m − 1 j ⋅ i = 0 ∑ n [ i > ⌊ a j ⋅ c − c − b − 1 ⌋ ] ) + 2 ⋅ ( j = 0 ∑ m − 1 i = 0 ∑ n [ i > ⌊ a j ⋅ c − c − b − 1 ⌋ ] ) − f ( a , b , c , n ) 再推
h
(
a
,
b
,
c
,
n
)
=
2
⋅
(
∑
j
=
0
m
−
1
j
⋅
(
n
−
⌊
j
⋅
c
−
c
−
b
−
1
a
⌋
)
)
+
2
⋅
(
∑
j
=
0
m
−
1
(
n
−
⌊
j
⋅
c
−
c
−
b
−
1
a
⌋
)
)
−
f
(
a
,
b
,
c
,
n
)
h(a,b,c,n) = 2 \cdot( \sum_{j = 0}^{m - 1} j \cdot (n - \lfloor { j \cdot c - c - b - 1 \over a} \rfloor) ) \\ + 2 \cdot( \sum_{j = 0}^{m - 1}(n - \lfloor { j \cdot c - c - b - 1 \over a} \rfloor) ) - f(a , b , c , n )
h ( a , b , c , n ) = 2 ⋅ ( j = 0 ∑ m − 1 j ⋅ ( n − ⌊ a j ⋅ c − c − b − 1 ⌋ ) ) + 2 ⋅ ( j = 0 ∑ m − 1 ( n − ⌊ a j ⋅ c − c − b − 1 ⌋ ) ) − f ( a , b , c , n ) 得出:
h
(
a
,
b
,
c
,
n
)
=
m
⋅
(
m
−
1
)
⋅
n
−
2
⋅
g
(
c
,
c
−
b
−
1
,
a
,
m
−
1
)
+
2
⋅
m
⋅
n
−
2
⋅
f
(
c
,
c
−
b
−
1
,
a
,
m
−
1
)
−
f
(
a
,
b
,
c
,
n
)
h(a,b,c,n) = m \cdot (m - 1) \cdot n - 2 \cdot g( c , c - b - 1 , a , m - 1 ) \\ + 2 \cdot m \cdot n - 2 \cdot f(c , c - b - 1 , a , m - 1) - f(a , b ,c , n)
h ( a , b , c , n ) = m ⋅ ( m − 1 ) ⋅ n − 2 ⋅ g ( c , c − b − 1 , a , m − 1 ) + 2 ⋅ m ⋅ n − 2 ⋅ f ( c , c − b − 1 , a , m − 1 ) − f ( a , b , c , n ) 最终得出:
h
(
a
,
b
,
c
,
n
)
=
m
⋅
(
m
+
1
)
⋅
n
−
2
⋅
g
(
c
,
c
−
b
−
1
,
a
,
m
−
1
)
−
2
⋅
f
(
c
,
c
−
b
−
1
,
a
,
m
−
1
)
−
f
(
a
,
b
,
c
,
n
)
h(a,b,c,n) = m \cdot (m + 1) \cdot n - 2 \cdot g( c , c - b - 1 , a , m - 1 ) \\ - 2 \cdot f(c , c - b - 1 , a , m - 1) - f(a , b ,c , n)
h ( a , b , c , n ) = m ⋅ ( m + 1 ) ⋅ n − 2 ⋅ g ( c , c − b − 1 , a , m − 1 ) − 2 ⋅ f ( c , c − b − 1 , a , m − 1 ) − f ( a , b , c , n ) 终于推完了,长长地松一口气 ,\ ( ^ o ^ ) /~
g
g
g ,
h
h
h 的实现比较复杂,因为要相互调用,最好用结构体维护。
板子
板子(f,g,h都有,三个愿望一次满足 ) 这题数据较大,要对998244353取模,公式中有除以二除以六的操作,要使用拓展欧几里得求乘法逆元。 这题要勤取模,否则会WRONG。 示例代码
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
#define mod 998244353
using namespace std;
struct node{
ll f;
ll g;
ll h;
} ;
ll inv2 , inv6;
inline void read ( ll & res ) {
res = 0 ;
ll pd = 1 ;
char aa = getchar ( ) ;
while ( aa < '0' || aa > '9' ) {
if ( aa == '-' ) {
pd = - pd;
}
aa = getchar ( ) ;
}
while ( aa >= '0' && aa <= '9' ) {
res = ( res << 1 ) + ( res << 3 ) + ( aa - '0' ) ;
aa = getchar ( ) ;
}
res * = pd;
return ;
}
inline node solve ( ll a , ll b , ll c , ll n ) {
if ( ! a ) {
node ans;
ans. f = ( n + 1 ) % mod * ( b / c ) % mod;
ans. g = n % mod * ( n + 1 ) % mod * inv2 % mod * ( b / c ) % mod;
ans. h = ( n + 1 ) % mod * ( b / c ) % mod * ( b / c ) % mod;
ans. f % = mod;
ans. g % = mod;
ans. h % = mod;
return ans;
}
if ( a >= c || b >= c ) {
node tem = solve ( a % c , b % c , c , n ) ;
node ans;
ans. f = ( tem. f + n % mod * ( n + 1 ) % mod * inv2 % mod * ( a / c ) % mod) % mod + ( n + 1 ) % mod * ( b / c ) % mod;
ans. g = ( tem. g + n % mod * ( n + 1 ) % mod * ( 2 * n + 1 ) % mod * inv6 % mod * ( a / c ) % mod ) % mod
+ n % mod * ( n + 1 ) % mod * inv2 % mod * ( b / c ) % mod;
ans. h = ( ( ( tem. h + n % mod * ( n + 1 ) % mod * ( 2 * n + 1 ) % mod * inv6 % mod * ( a / c ) % mod * ( a / c ) % mod) % mod
+ ( n + 1 ) % mod * ( b / c ) % mod * ( b / c ) % mod
+ 2 * ( b / c ) % mod * tem. f % mod) % mod + 2 * ( a / c ) % mod * tem. g % mod) % mod
+ ( a / c ) % mod * ( b / c ) % mod * n % mod * ( n + 1 ) % mod;
ans. f % = mod;
ans. g % = mod;
ans. h % = mod;
return ans;
}
ll m = ( ( a * n + b ) / c ) ;
node tem = solve ( c , c - b - 1 , a , m - 1 ) ;
node ans;
ans. f = n * ( m % mod ) % mod - tem. f;
ans. f % = mod;
ans. g = ( n * ( m % mod ) % mod * ( 1 + n ) % mod * inv2 % mod) % mod - tem. h * inv2 % mod - tem. f * inv2 % mod;
ans. h = ( ( m % mod ) * ( ( m + 1 ) % mod ) % mod * n) % mod - 2 * tem. g % mod - 2 * tem. f % mod - ans. f;
ans. g % = mod;
ans. h % = mod;
return ans;
}
inline ll exgcd ( ll a , ll b , ll & x , ll & y ) {
if ( ! b ) {
x = 1 ;
y = 0 ;
return a;
}
ll d = exgcd ( b , a % b , x , y ) ;
ll tem = x;
x = y;
y = tem - a / b * y;
return d;
}
int main ( ) {
ll temp;
exgcd ( 2 , mod , inv2 , temp ) ;
exgcd ( 6 , mod , inv6 , temp ) ;
while ( inv2 < 0 ) {
inv2 + = mod;
}
while ( inv6 < 0 ) {
inv6 + = mod;
}
ll t , a , b , c , n;
read ( t) ;
while ( t-- ) {
read ( n) ;
read ( a) ;
read ( b) ;
read ( c) ;
node ans = solve ( a , b , c , n ) ;
printf ( "%lld %lld %lld\n" , ( ans. f + mod ) % mod, ( ans. h + mod ) % mod, ( ans. g + mod ) % mod) ;
}
return 0 ;
}
推荐好题
Earthquake https://www.luogu.org/problem/P5171 Sum https://www.luogu.org/problem/P5172 Fraction https://www.luogu.org/problem/P5179
题解等我搞定了再贴吧