几个等式
其中
⌊
⌋
\lfloor \rfloor
⌊⌋表示向下取整,
⌈
⌉
\lceil \rceil
⌈⌉表示向上取整。
a
≤
⌊
b
c
⌋
⇔
a
⋅
c
≤
b
a \le \lfloor { b \over c } \rfloor \Leftrightarrow a \cdot c \le b
a≤⌊cb⌋⇔a⋅c≤b
a
<
⌈
b
c
⌉
⇔
a
⋅
c
<
b
a \lt \lceil { b \over c } \rceil \Leftrightarrow a \cdot c \lt b
a<⌈cb⌉⇔a⋅c<b
a
≥
⌈
b
c
⌉
⇔
a
⋅
c
≥
b
a \ge \lceil { b \over c } \rceil \Leftrightarrow a \cdot c \ge b
a≥⌈cb⌉⇔a⋅c≥b
a
>
⌊
b
c
⌋
⇔
a
⋅
c
>
b
a \gt \lfloor { b \over c } \rfloor \Leftrightarrow a \cdot c \gt b
a>⌊cb⌋⇔a⋅c>b
上面四个式子可以这么理解:趋近可能取等,趋远不可能取等。
⌈
b
c
⌉
⇔
⌊
b
+
c
−
1
c
⌋
\lceil{ b \over c } \rceil \Leftrightarrow \lfloor{ b + c - 1 \over c } \rfloor
⌈cb⌉⇔⌊cb+c−1⌋
⌊
b
c
⌋
⇔
⌈
b
−
c
+
1
c
⌉
\lfloor{ b \over c } \rfloor \Leftrightarrow \lceil{ b - c + 1 \over c } \rceil
⌊cb⌋⇔⌈cb−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⌊ca⋅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∑ni⋅⌊ca⋅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⌊ca⋅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⌊ca⋅i+b⌋
分类讨论:
1.
a
=
0
a = 0
a=0 , 此时返回
(
n
+
1
)
⋅
⌊
b
c
⌋
(n + 1) \cdot \lfloor {b \over c}\rfloor
(n+1)⋅⌊cb⌋,以下情况
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
⌊ca⋅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
⌊ca⌋⋅i +
⌊
b
c
⌋
\lfloor{ b \over c} \rfloor
⌊cb⌋
则
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)+2n⋅(n+1)⋅⌊ca⌋+(n+1)⋅⌊cb⌋
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=⌊ca⋅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⌊ca⋅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∑nj=1∑m[⌊ca⋅i+b⌋≥j]
这个在几何上,可以理解为引一条直线
y
=
a
⋅
x
+
b
c
y = { a \cdot x + b \over c}
y=ca⋅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∑nj=0∑m−1[⌊ca⋅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∑nj=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∑nj=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∑nj=0∑m−1[i>aj⋅c+c−b−1]两个sigma符号可交换位置(严谨的数学证明我不会,但是脑补一下码两个for循环时,交换两个互不影响(起止点独立)的两个for循环时,不影响结果)。交换后再用
∑
i
=
0
n
\sum_{i = 0}^n
∑i=0n把
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
⌊aj⋅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−⌊aj⋅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∑ni2=6n⋅(n+1)⋅(2n+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=n3+3⋅n2+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−n3=3⋅n2+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
n3−(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
33−23=3⋅22+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
23−13=3⋅12+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∑ni2)+3∗(i=0∑ni)+n因为
∑
i
=
0
n
i
=
n
⋅
(
n
+
1
)
2
\sum_{i=0}^n i = { n \cdot (n + 1) \over 2 }
i=0∑ni=2n⋅(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∑ni2+23⋅(n+1)⋅n+n=n3+3⋅n2+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∑ni2=6n⋅(n+1)⋅(2n+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∑ni⋅⌊ca⋅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
2n⋅(n+1)⋅⌊cb⌋
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)+6n⋅(n+1)⋅(2⋅n+1)∗⌊ca⌋+2n⋅(n+1)∗⌊cb⌋
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∑ni⋅j=1∑m[⌊ca⋅i+b⌋≥j]
m
=
⌊
a
⋅
n
+
b
c
⌋
m = \lfloor { a \cdot n + b \over c } \rfloor
m=⌊ca⋅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∑ni⋅j=0∑m−1[i>aj⋅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
⌊aj⋅c+c−b−1⌋+1,其实这个上面已讲过了 。
设
t
=
⌊
j
⋅
c
+
c
−
b
−
1
a
⌋
t = \lfloor { j \cdot c + c - b - 1 \over a }\rfloor
t=⌊aj⋅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−1i=t+1∑ni不难发现这其实是一个等差数列
s
n
′
=
(
a
1
+
a
n
′
)
⋅
n
′
2
s_{n'} = { (a_1 + a_{n'}) \cdot n' \over 2 }
sn′=2(a1+an′)⋅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−12(t+1+n)⋅(n−t)
a
1
a_1
a1对应
t
+
1
t + 1
t+1 ,
a
n
′
a_{n'}
an′对应
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)=2n⋅m⋅(1+n)−j=0∑m−12t−j=0∑m−12t2
恢复
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)=2n⋅m⋅(1+n)−21⋅h(c,c−b−1,a,m−1)−21⋅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⌊ca⋅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)⋅⌊cb⌋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⌊ca⋅i+b⌋2=i=0∑n[⌊ca⌋∗i+⌊cb⌋+(ca%c∗i+cb%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=x2+y2+z2+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)+6n⋅(n+1)⋅(2⋅n+1)⋅⌊ca⌋2+(n+1)⋅⌊cb⌋2+2⋅⌊cb⌋⋅f(a%c,b%c,c,n)+2⋅⌊ca⌋⋅g(a%c,b%c,c,n)+⌊ca⌋⋅⌊cb⌋⋅n⋅(n+1)
3. 若
a
<
c
a \lt c
a<c且
b
<
c
b \lt c
b<c时,
考虑把狰狞的
x
2
x^2
x2拆一下,可得:
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
x2=2⋅2x⋅(x+1)−x=2⋅i=0∑xi−x利用这个拆开原式,并设
m
=
⌊
a
⋅
n
+
b
c
⌋
m = \lfloor {a \cdot n + b \over c} \rfloor
m=⌊ca⋅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∑⌊ca⋅i+b⌋j)−⌊ca⋅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⌊ca⋅i+b⌋j和
⌊
a
⋅
i
+
b
c
⌋
\lfloor {a \cdot i + b \over c} \rfloor
⌊ca⋅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[⌊ca⋅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−1j⋅i=0∑n[⌊ca⋅i+b⌋≥j+1])+2⋅(j=0∑m−1i=0∑n[⌊ca⋅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−1j⋅i=0∑n[i>⌊aj⋅c−c−b−1⌋])+2⋅(j=0∑m−1i=0∑n[i>⌊aj⋅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−1j⋅(n−⌊aj⋅c−c−b−1⌋))+2⋅(j=0∑m−1(n−⌊aj⋅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;//乘法逆元
}
//printf("%lld %lld",inv2,inv6);
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
题解等我搞定了再贴吧