类欧几里得算法是用 O ( log n ) O(\log n) O(logn) 时间求形如 ∑ i = 0 n ⌊ a i + b c ⌋ \sum\limits_{i=0}^n\left\lfloor\dfrac{ai+b}{c}\right \rfloor i=0∑n⌊cai+b⌋ 的式子的答案的。 a , c > 0 , b ≥ 0 a,c>0,b\ge0 a,c>0,b≥0
类欧几里得算法
设 f ( n , a , b , c ) = ∑ i = 0 n ⌊ a i + b c ⌋ f(n,a,b,c)=\sum\limits_{i=0}^n\left\lfloor\dfrac{ai+b}{c}\right \rfloor f(n,a,b,c)=i=0∑n⌊cai+b⌋。
我们可以把
a
,
b
a,b
a,b 对
c
c
c 取模。
f
(
n
,
a
,
b
,
c
)
=
∑
i
=
0
n
⌊
(
c
⌊
a
c
⌋
+
a
m
o
d
c
)
i
+
c
⌊
b
c
⌋
+
b
m
o
d
c
c
⌋
=
∑
i
=
0
n
⌊
a
c
⌋
i
+
⌊
b
c
⌋
+
⌊
(
a
m
o
d
c
)
i
+
b
m
o
d
c
c
⌋
=
⌊
a
c
⌋
n
(
n
+
1
)
2
+
(
n
+
1
)
⌊
b
c
⌋
+
f
(
n
,
a
m
o
d
c
,
b
m
o
d
c
,
c
)
\begin{aligned} f(n,a,b,c)&=\sum\limits_{i=0}^n\left\lfloor\dfrac{(c\lfloor\frac ac\rfloor+a\bmod c)i+c\lfloor\frac bc\rfloor+b\bmod c}{c}\right \rfloor\\ &=\sum\limits_{i=0}^n\left\lfloor\dfrac ac\right\rfloor i+\left\lfloor\dfrac bc\right\rfloor+\left\lfloor\dfrac{(a\bmod c)i+b\bmod c}{c}\right \rfloor\\ &=\left\lfloor\dfrac ac\right\rfloor\dfrac{n(n+1)}{2}+(n+1)\left\lfloor\dfrac bc\right\rfloor+f(n,a\bmod c,b\bmod c,c)\\ \end{aligned}
f(n,a,b,c)=i=0∑n⌊c(c⌊ca⌋+amodc)i+c⌊cb⌋+bmodc⌋=i=0∑n⌊ca⌋i+⌊cb⌋+⌊c(amodc)i+bmodc⌋=⌊ca⌋2n(n+1)+(n+1)⌊cb⌋+f(n,amodc,bmodc,c)
下面的 a , b a,b a,b 都是模过 c c c 的。
考虑继续化简变换。设 m = ⌊ a n + b c ⌋ m=\left\lfloor\dfrac{an+b}{c}\right \rfloor m=⌊can+b⌋
f ( n , a , b , c ) = ∑ i = 0 n ⌊ a i + b c ⌋ = ∑ i = 0 n ∑ j = 0 ⌊ a i + b c ⌋ − 1 1 = ∑ j = 0 m − 1 ∑ i = 0 n [ j < ⌊ a i + b c ⌋ ] = ∑ j = 0 m − 1 ∑ i = 0 n [ j + 1 ≤ ⌊ a i + b c ⌋ ] = ∑ j = 0 m − 1 ∑ i = 0 n [ j + 1 ≤ a i + b c ] = ∑ j = 0 m − 1 ∑ i = 0 n [ c j + c − b − 1 < a i ] = ∑ j = 0 m − 1 ∑ i = 0 n [ ⌊ c j + c − b − 1 a ⌋ < i ] = ∑ j = 0 m − 1 ( n − ⌊ c j + c − b − 1 a ⌋ ) = n m − f ( m − 1 , c , c − b − 1 , a ) \begin{aligned} f(n,a,b,c)&=\sum\limits_{i=0}^n\left\lfloor\frac{ai+b}{c}\right\rfloor\\ &=\sum\limits_{i=0}^n\sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right \rfloor-1}1\\ &=\sum\limits_{j=0}^{m-1}\sum\limits_{i=0}^n\left[j<\left\lfloor\dfrac{ai+b}{c}\right \rfloor\right]\\ &=\sum\limits_{j=0}^{m-1}\sum\limits_{i=0}^n\left[j+1\le\left\lfloor\dfrac{ai+b}{c}\right \rfloor\right]\\ &=\sum\limits_{j=0}^{m-1}\sum\limits_{i=0}^n\left[j+1\le\dfrac{ai+b}{c}\right]\\ &=\sum\limits_{j=0}^{m-1}\sum\limits_{i=0}^n\left[cj+c-b-1< ai\right]\\ &=\sum\limits_{j=0}^{m-1}\sum\limits_{i=0}^n\left[\left\lfloor\dfrac{cj+c-b-1}{a}\right\rfloor<i\right]\\ &=\sum\limits_{j=0}^{m-1}\left(n-\left\lfloor\dfrac{cj+c-b-1}{a}\right\rfloor\right)\\ &=nm-f(m-1,c,c-b-1,a)\\ \end{aligned} f(n,a,b,c)=i=0∑n⌊cai+b⌋=i=0∑nj=0∑⌊cai+b⌋−11=j=0∑m−1i=0∑n[j<⌊cai+b⌋]=j=0∑m−1i=0∑n[j+1≤⌊cai+b⌋]=j=0∑m−1i=0∑n[j+1≤cai+b]=j=0∑m−1i=0∑n[cj+c−b−1<ai]=j=0∑m−1i=0∑n[⌊acj+c−b−1⌋<i]=j=0∑m−1(n−⌊acj+c−b−1⌋)=nm−f(m−1,c,c−b−1,a)
这样,我们就得到一个递推式。发现 a , c a,c a,c 位置调换了,而且 a a a 还模了 c c c。这类似于辗转相除法,故时间复杂度是 O ( log n ) O(\log n) O(logn) 的。
其实这个算法只有时间复杂度和欧几里得扯得上关系。
下面是参考实现代码
ll f(ll n,ll a,ll b,ll c)
{
if(!a) return (n+1)*(b/c);
if(a>=c||b>=c) return f(n,a%c,b%c,c)+n*(n+1)/2*(a/c)+(n+1)*(b/c);
return (a*n+b)/c*n-f((a*n+b)/c-1,c,c-b-1,a);
}
拓展
求 ∑ i = 0 n i ⌊ a i + b c ⌋ , ∑ i = 0 n ⌊ a i + b c ⌋ 2 \sum\limits_{i=0}^ni\left\lfloor\dfrac{ai+b}{c}\right \rfloor,\sum\limits_{i=0}^n\left\lfloor\dfrac{ai+b}{c}\right \rfloor^2 i=0∑ni⌊cai+b⌋,i=0∑n⌊cai+b⌋2
设 g ( n , a , b , c ) = ∑ i = 0 n i ⌊ a i + b c ⌋ , h ( n , a , b , c ) = ∑ i = 0 n ⌊ a i + b c ⌋ 2 g(n,a,b,c)=\sum\limits_{i=0}^ni\left\lfloor\dfrac{ai+b}{c}\right \rfloor,h(n,a,b,c)=\sum\limits_{i=0}^n\left\lfloor\dfrac{ai+b}{c}\right \rfloor^2 g(n,a,b,c)=i=0∑ni⌊cai+b⌋,h(n,a,b,c)=i=0∑n⌊cai+b⌋2
求
g
g
g:首先
a
,
b
a,b
a,b 对
c
c
c 取模。类似得到
g
(
n
,
a
,
b
,
c
)
=
∑
i
=
0
n
i
⌊
(
c
⌊
a
c
⌋
+
a
m
o
d
c
)
i
+
c
⌊
b
c
⌋
+
b
m
o
d
c
c
⌋
=
∑
i
=
0
n
(
i
2
⌊
a
c
⌋
+
i
⌊
b
c
⌋
+
i
⌊
(
a
m
o
d
c
)
i
+
b
m
o
d
c
c
⌋
)
=
⌊
a
c
⌋
n
(
n
+
1
)
(
2
n
+
1
)
6
+
⌊
b
c
⌋
n
(
n
+
1
)
2
+
g
(
n
,
a
m
o
d
c
,
b
m
o
d
c
,
c
)
\begin{aligned} g(n,a,b,c)&=\sum\limits_{i=0}^ni\left\lfloor\dfrac{(c\lfloor\frac ac\rfloor+a\bmod c)i+c\lfloor\frac bc\rfloor+b\bmod c}{c}\right \rfloor\\ &=\sum\limits_{i=0}^n\left(i^2\left\lfloor\frac ac\right\rfloor+i\left\lfloor\frac bc\right\rfloor+i\left\lfloor\dfrac{(a\bmod c)i+b\bmod c}{c}\right \rfloor\right)\\ &=\left\lfloor\frac ac\right\rfloor\dfrac{n(n+1)(2n+1)}{6}+\left\lfloor\frac bc\right\rfloor\dfrac{n(n+1)}{2}+g(n,a\bmod c,b\bmod c,c) \end{aligned}
g(n,a,b,c)=i=0∑ni⌊c(c⌊ca⌋+amodc)i+c⌊cb⌋+bmodc⌋=i=0∑n(i2⌊ca⌋+i⌊cb⌋+i⌊c(amodc)i+bmodc⌋)=⌊ca⌋6n(n+1)(2n+1)+⌊cb⌋2n(n+1)+g(n,amodc,bmodc,c)
设 p = ⌊ c j + c − b − 1 a ⌋ p=\left\lfloor\dfrac{cj+c-b-1}{a}\right\rfloor p=⌊acj+c−b−1⌋
g ( n , a , b , c ) = ∑ i = 0 n i ⌊ a i + b c ⌋ = ∑ i = 0 n ∑ j = 0 ⌊ a i + b c ⌋ − 1 i = ∑ j = 0 m − 1 ∑ i = 0 n [ j < ⌊ a i + b c ⌋ ] i = ∑ j = 0 m − 1 ∑ i = 0 n [ j + 1 ≤ a i + b c ] i = ∑ j = 0 m − 1 ∑ i = 0 n [ p < i ] i = ∑ j = 0 m − 1 ( n + p + 1 ) ( n − p ) 2 = 1 2 ∑ j = 0 m − 1 ( n 2 + n − p 2 − p ) = 1 2 ( n m ( n + 1 ) − ∑ j = 0 m − 1 p 2 − ∑ j = 0 m − 1 p ) = 1 2 ( n m ( n + 1 ) − h ( m − 1 , c , c − b − 1 , a ) − f ( m − 1 , c , c − b − 1 , a ) ) \begin{aligned} g(n,a,b,c)&=\sum\limits_{i=0}^ni\left\lfloor\dfrac{ai+b}{c}\right \rfloor\\ &=\sum\limits_{i=0}^n\sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right \rfloor-1}i\\ &=\sum\limits_{j=0}^{m-1}\sum\limits_{i=0}^n\left[j<\left\lfloor\dfrac{ai+b}{c}\right \rfloor\right]i\\ &=\sum\limits_{j=0}^{m-1}\sum\limits_{i=0}^n\left[j+1\le\dfrac{ai+b}{c}\right]i\\ &=\sum\limits_{j=0}^{m-1}\sum\limits_{i=0}^n\left[p<i\right]i\\ &=\sum\limits_{j=0}^{m-1}\dfrac{(n+p+1)(n-p)}{2}\\ &=\dfrac12\sum\limits_{j=0}^{m-1}\left(n^2+n-p^2-p\right)\\ &=\dfrac12\left(nm(n+1)-\sum\limits_{j=0}^{m-1}p^2-\sum\limits_{j=0}^{m-1}p\right)\\ &=\dfrac12\left(nm(n+1)-h(m-1,c,c-b-1,a)-f(m-1,c,c-b-1,a)\right) \end{aligned} g(n,a,b,c)=i=0∑ni⌊cai+b⌋=i=0∑nj=0∑⌊cai+b⌋−1i=j=0∑m−1i=0∑n[j<⌊cai+b⌋]i=j=0∑m−1i=0∑n[j+1≤cai+b]i=j=0∑m−1i=0∑n[p<i]i=j=0∑m−12(n+p+1)(n−p)=21j=0∑m−1(n2+n−p2−p)=21(nm(n+1)−j=0∑m−1p2−j=0∑m−1p)=21(nm(n+1)−h(m−1,c,c−b−1,a)−f(m−1,c,c−b−1,a))
发现这里 g g g 函数的递归调用了 h h h,接下来求 h h h。 a , b a,b a,b 还是要对 c c c 取模。
h ( n , a , b , c ) = ∑ i = 0 n ⌊ ( c ⌊ a c ⌋ + a m o d c ) i + c ⌊ b c ⌋ + b m o d c c ⌋ 2 = ∑ i = 0 n ( i ⌊ a c ⌋ + ⌊ b c ⌋ + ⌊ ( a m o d c ) i + b m o d c c ⌋ ) 2 = ∑ i = 0 n ( i 2 ⌊ a c ⌋ 2 + ⌊ b c ⌋ 2 + ⌊ ( a m o d c ) i + b m o d c c ⌋ 2 + 2 i ⌊ a c ⌋ ⌊ b c ⌋ + 2 i ⌊ a c ⌋ ⌊ ( a m o d c ) i + b m o d c c ⌋ + 2 ⌊ b c ⌋ ⌊ ( a m o d c ) i + b m o d c c ⌋ ) = ⌊ a c ⌋ 2 n ( n + 1 ) ( 2 n + 1 ) 6 + ⌊ b c ⌋ 2 ( n + 1 ) + ⌊ a c ⌋ ⌊ b c ⌋ n ( n + 1 ) + h ( n , a m o d c , b m o d c , c ) + 2 ⌊ a c ⌋ g ( n , a m o d c , b m o d c , c ) + 2 ⌊ b c ⌋ f ( n , a m o d c , b m o d c , c ) \begin{aligned} h(n,a,b,c)&=\sum\limits_{i=0}^n\left\lfloor\dfrac{(c\lfloor\frac ac\rfloor+a\bmod c)i+c\lfloor\frac bc\rfloor+b\bmod c}{c}\right \rfloor^2\\ &=\sum\limits_{i=0}^n\left(i\left\lfloor\frac ac\right\rfloor+\left\lfloor\frac bc\right\rfloor+\left\lfloor\dfrac{(a\bmod c)i+b\bmod c}{c}\right \rfloor\right)^2\\ &=\sum\limits_{i=0}^n\left(i^2\left\lfloor\frac ac\right\rfloor^2+\left\lfloor\frac bc\right\rfloor^2+\left\lfloor\dfrac{(a\bmod c)i+b\bmod c}{c}\right \rfloor^2+2i\left\lfloor\frac ac\right\rfloor\left\lfloor\frac bc\right\rfloor+2i\left\lfloor\frac ac\right\rfloor\left\lfloor\dfrac{(a\bmod c)i+b\bmod c}{c}\right \rfloor+2\left\lfloor\frac bc\right\rfloor\left\lfloor\dfrac{(a\bmod c)i+b\bmod c}{c}\right\rfloor\right)\\ &=\left\lfloor\frac ac\right\rfloor^2\dfrac{n(n+1)(2n+1)}{6}+\left\lfloor\frac bc\right\rfloor^2(n+1)+\left\lfloor\frac ac\right\rfloor\left\lfloor\frac bc\right\rfloor n(n+1)+h(n,a\bmod c,b\bmod c,c)+2\left\lfloor\frac ac\right\rfloor g(n,a\bmod c,b\bmod c,c)+2\left\lfloor\frac bc\right\rfloor f(n,a\bmod c,b\bmod c,c) \end{aligned} h(n,a,b,c)=i=0∑n⌊c(c⌊ca⌋+amodc)i+c⌊cb⌋+bmodc⌋2=i=0∑n(i⌊ca⌋+⌊cb⌋+⌊c(amodc)i+bmodc⌋)2=i=0∑n(i2⌊ca⌋2+⌊cb⌋2+⌊c(amodc)i+bmodc⌋2+2i⌊ca⌋⌊cb⌋+2i⌊ca⌋⌊c(amodc)i+bmodc⌋+2⌊cb⌋⌊c(amodc)i+bmodc⌋)=⌊ca⌋26n(n+1)(2n+1)+⌊cb⌋2(n+1)+⌊ca⌋⌊cb⌋n(n+1)+h(n,amodc,bmodc,c)+2⌊ca⌋g(n,amodc,bmodc,c)+2⌊cb⌋f(n,amodc,bmodc,c)
虽然挺复杂,但还是能表示。
继续求值,和上面差不多,但是有点不一样。
如果要把 ⌊ a i + b c ⌋ 2 \left\lfloor\dfrac{ai+b}{c}\right\rfloor^2 ⌊cai+b⌋2 像上面一样转化,就变成 ∑ j = 0 ⌊ a i + b c ⌋ − 1 ∑ j = 0 ⌊ a i + b c ⌋ − 1 1 \sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right \rfloor-1}\sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right \rfloor-1}1 j=0∑⌊cai+b⌋−1j=0∑⌊cai+b⌋−11,有两个求和符号,不好处理,考虑换一种表示方式。下面的 m , p m,p m,p 和上面的是一样的。
由于 n 2 = 2 ⋅ n ( n + 1 ) 2 − n = 2 ∑ i = 1 n i − n n^2=2\cdot \dfrac{n(n+1)}{2}-n=2\sum\limits_{i=1}^ni-n n2=2⋅2n(n+1)−n=2i=1∑ni−n
所以
h
(
n
,
a
,
b
,
c
)
=
∑
i
=
0
n
⌊
a
i
+
b
c
⌋
2
=
∑
i
=
0
n
(
2
∑
j
=
1
⌊
a
i
+
b
c
⌋
j
−
⌊
a
i
+
b
c
⌋
)
=
2
∑
i
=
0
n
∑
j
=
0
⌊
a
i
+
b
c
⌋
−
1
(
j
+
1
)
−
f
(
n
,
a
,
b
,
c
)
\begin{aligned} h(n,a,b,c)&=\sum\limits_{i=0}^n\left\lfloor\dfrac{ai+b}{c}\right\rfloor^2\\ &=\sum\limits_{i=0}^n\left(2\sum\limits_{j=1}^{\left\lfloor\frac{ai+b}{c}\right\rfloor}j-\left\lfloor\dfrac{ai+b}{c}\right\rfloor\right)\\ &=2\sum\limits_{i=0}^n\sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right\rfloor-1}(j+1)-f(n,a,b,c) \end{aligned}
h(n,a,b,c)=i=0∑n⌊cai+b⌋2=i=0∑n
2j=1∑⌊cai+b⌋j−⌊cai+b⌋
=2i=0∑nj=0∑⌊cai+b⌋−1(j+1)−f(n,a,b,c)
只看前面
=
2
∑
i
=
0
n
∑
j
=
0
⌊
a
i
+
b
c
⌋
−
1
(
j
+
1
)
=
2
∑
j
=
0
m
−
1
(
j
+
1
)
∑
i
=
0
n
[
j
<
⌊
a
i
+
b
c
⌋
]
=
2
∑
j
=
0
m
−
1
(
j
+
1
)
∑
i
=
0
n
[
p
<
i
]
=
2
∑
j
=
0
m
−
1
(
j
+
1
)
(
n
−
p
)
=
2
∑
j
=
0
m
−
1
(
n
(
j
+
1
)
−
p
j
−
p
)
=
n
m
(
m
+
1
)
−
2
g
(
m
−
1
,
c
,
c
−
b
−
1
,
a
)
−
2
f
(
m
−
1
,
c
,
c
−
b
−
1
,
a
)
\begin{aligned} &=2\sum\limits_{i=0}^n\sum\limits_{j=0}^{\left\lfloor\frac{ai+b}{c}\right\rfloor-1}(j+1)\\ &=2\sum\limits_{j=0}^{m-1}(j+1)\sum\limits_{i=0}^{n}\left[j<\left\lfloor\dfrac{ai+b}{c}\right\rfloor\right]\\ &=2\sum\limits_{j=0}^{m-1}(j+1)\sum\limits_{i=0}^{n}\left[p<i\right]\\ &=2\sum\limits_{j=0}^{m-1}(j+1)(n-p)\\ &=2\sum\limits_{j=0}^{m-1}\left(n(j+1)-pj-p\right)\\ &=nm(m+1)-2g(m-1,c,c-b-1,a)-2f(m-1,c,c-b-1,a) \end{aligned}
=2i=0∑nj=0∑⌊cai+b⌋−1(j+1)=2j=0∑m−1(j+1)i=0∑n[j<⌊cai+b⌋]=2j=0∑m−1(j+1)i=0∑n[p<i]=2j=0∑m−1(j+1)(n−p)=2j=0∑m−1(n(j+1)−pj−p)=nm(m+1)−2g(m−1,c,c−b−1,a)−2f(m−1,c,c−b−1,a)
即 h ( n , a , b , c ) = n m 2 − 2 g ( m − 1 , c , c − b − 1 , a ) − f ( m − 1 , c , c − b − 1 , a ) h(n,a,b,c)=nm^2-2g(m-1,c,c-b-1,a)-f(m-1,c,c-b-1,a) h(n,a,b,c)=nm2−2g(m−1,c,c−b−1,a)−f(m−1,c,c−b−1,a)
f , g , h f,g,h f,g,h 相互调用,但是里面参数变化是一致的。所以可以同时递归求 f , g , h f,g,h f,g,h,时间复杂度为 O ( log n ) O(\log n) O(logn)。
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=998244353,inv2=499122177,inv6=166374059;
ll n,a,b,c;
struct node
{
ll f,g,h;
};
node solve(ll n,ll a,ll b,ll c)
{
if(!a) return {b/c*(n+1)%mod,b/c*n%mod*(n+1)%mod*inv2%mod,(b/c)*(b/c)%mod*(n+1)%mod};
if(a>=c||b>=c){
node x=solve(n,a%c,b%c,c);
x.h=((a/c)*(a/c)%mod*n%mod*(n+1)%mod*(2*n+1)%mod*inv6%mod+(b/c)*(b/c)%mod*(n+1)%mod+(a/c)*(b/c)%mod*n%mod*(n+1)%mod+x.h+a/c*2*x.g+b/c*2*x.f)%mod;
x.f=(x.f+a/c*n%mod*(n+1)%mod*inv2%mod+b/c*(n+1))%mod;
x.g=(x.g+a/c*n%mod*(n+1)%mod*(2*n+1)%mod*inv6%mod+b/c*n%mod*(n+1)%mod*inv2)%mod;
return x;
}
ll m=(a*n+b)/c;
node x=solve(m-1,c,c-b-1,a),ans;
ans.f=(n*m%mod-x.f+mod)%mod;
ans.g=inv2*(n*m%mod*(n+1)%mod-x.h-x.f+2*mod)%mod;
ans.h=(n*m%mod*m%mod-2*x.g-x.f+4*mod)%mod;
return ans;
}
int main()
{
int t;
cin>>t;
while(t--){
scanf("%lld%lld%lld%lld",&n,&a,&b,&c);
node ans=solve(n,a,b,c);
printf("%lld %lld %lld\n",ans.f,ans.h,ans.g);
}
}
1451

被折叠的 条评论
为什么被折叠?



