类欧几里得
类欧几里得
简介
基础的类欧几里得有三种形式,可以用来快速求出者三种形式的值。
\[f(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{ai+b}c\rfloor
\]
\[g(a,b,c,n)=\sum_{i=0}^ni\lfloor\frac{ai+b}c\rfloor
\]
\[h(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{ai+b}c\rfloor^2
\]
令 \(m=\lfloor\frac{ai+b}c\rfloor\)
推\(f\)式(最简单)
\[f(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{ai+b}c\rfloor
\]
如果 \(a\ge c\) 或 \(b\ge c\):
\[\begin{aligned}
f(a,b,c,n)&=\lfloor\frac ac\rfloor\frac {n(n+1)}2+\lfloor\frac bc\rfloor(n+1)+\sum_{i=0}^n\lfloor\frac{(a\bmod c)i+(b\bmod c)}{c}\rfloor \\
&=\lfloor\frac ac\rfloor\frac {n(n+1)}2+\lfloor\frac bc\rfloor(n+1)+f(a\bmod c,b\bmod c,c,n)
\end{aligned}\]
如果 \(a,b\lt c\):
\[\begin{aligned}
f(a,b,c,n)&=\sum_{i=0}^n\lfloor\frac{ai+b}{c}\rfloor \\
&=\sum_{i=0}^n\sum_{j=0}^{\lfloor\frac {ai+b}c\rfloor-1}1 \\
&=\sum_{j=0}^{m-1}\sum_{i=0}^n[j\lt\lfloor\frac {ai+b}c\rfloor] \\
&=\sum_{j=0}^{m-1}\sum_{i=0}^n[cj\lt(ai+b)-c+1] \\
&=\sum_{j=0}^{m-1}\sum_{i=0}^n[\lfloor\frac{cj+c-b-1}a\rfloor\lt i] \\
&=\sum_{j=0}^{m-1}(n-\lfloor\frac{cj+c-b-1}a\rfloor) \\
&=nm-\sum_{j=0}^{m-1}\lfloor\frac{cj+c-b-1}a\rfloor \\
&=nm-f(c,c-b-1,a,m-1)
\end{aligned}\]
递归即可。
推\(g\)式
\[g(a,b,c,n)=\sum_{i=0}^ni\lfloor\frac{ai+b}c\rfloor
\]
如果 \(a\ge c\) 或 \(b\ge c\):
\[\begin{aligned}
g(a,b,c,n)&=\lfloor\frac ac\rfloor\frac{n(n+1)(2n+1)}6+\lfloor\frac bc\rfloor\frac{n(n+1)}2+\sum_{i=0}^ni\lfloor\frac{(a\bmod c)i+(b\bmod c)}{c}\rfloor \\
&=\lfloor\frac ac\rfloor\frac{n(n+1)(2n+1)}6+\lfloor\frac bc\rfloor\frac{n(n+1)}2+g(a\bmod c,b\bmod c,c,n)
\end{aligned}\]
如果 \(a,b\lt c\):
\[g(a,b,c,n)=\sum_{i=0}^ni\lfloor\frac{ai+b}c\rfloor
\]
\[=\sum_{i=0}^ni\sum_{j=0}^{\lfloor\frac{ai+b}c\rfloor-1}1
\]
\[=\sum_{j=0}^{m-1}\sum_{i=0}^n[j\lt\lfloor\frac{ai+b}c\rfloor]i
\]
\[=\sum_{j=0}^{m-1}\sum_{i=0}^n[cj\lt(ai+b)-c+1]i
\]
\[=\sum_{j=0}^{m-1}\sum_{i=0}^n[\lfloor\frac{cj+c-b-1}a\rfloor\lt i]i
\]
\[=\sum_{j=0}^{m-1}\frac{(n-\lfloor\frac{cj+c-b-1}a\rfloor)(n+\lfloor\frac{cj+c-b-1}a\rfloor+1)}2
\]
\[=\frac12\sum_{j=0}^{m-1}(n(n+1)-\lfloor\frac{cj+c-b-1}a\rfloor-\lfloor\frac{cj+c-b-1}a\rfloor^2)
\]
\[=\frac m2n(n+1)-\frac12\sum_{j=0}^{m-1}(\lfloor\frac{cj+c-b-1}a\rfloor+\lfloor\frac{cj+c-b-1}a\rfloor^2)
\]
\[=\frac m2n(n+1)-\frac12(f(c,c+b-1,a,m-1)+h(c,c+b-1,a,m-1))
\]
递归时需要用到 \(f\) 和 \(h\)。
推\(h\)式
\[h(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{ai+b}c\rfloor^2
\]
如果 \(a\ge c\) 或 \(b\ge c\):
\[h(a,b,c,n)=\sum_{i=0}^n(\lfloor\frac ac\rfloor i+\lfloor\frac bc\rfloor)^2+\sum_{i=0}^n2(\lfloor\frac ac\rfloor i +\lfloor\frac bc\rfloor)\lfloor\frac{(a\bmod c)i+(b\bmod c)}c\rfloor
\]
\[+\sum_{i=0}^n\lfloor\frac{(a\bmod c)i+(b\bmod c)}{c}\rfloor^2
\]
\[=\lfloor\frac ac\rfloor^2\frac{n(n+1)(2n+1)}6+\lfloor\frac bc\rfloor^2(n+1) +2\lfloor\frac ac\rfloor\lfloor\frac bc\rfloor\frac{n(n+1)}2
\]
\[+2\sum_{i=0}^n\lfloor\frac ac\rfloor i\lfloor\frac{(a\bmod c)i+(b\bmod c)}{c}\rfloor +2\sum_{i=0}^n\lfloor\frac bc\rfloor\lfloor\frac{(a\bmod c)i+(b\bmod c)}{c}\rfloor
\]
\[+\sum_{i=0}^n\lfloor\frac{(a\bmod c)i+(b\bmod c)}{c}\rfloor^2
\]
\[=\lfloor\frac ac\rfloor^2\frac{n(n+1)(2n+1)}6+\lfloor\frac bc\rfloor^2(n+1)
\]
\[+\lfloor\frac ac\rfloor\lfloor\frac bc\rfloor n(n+1) +2\lfloor\frac ac\rfloor g(a\bmod c,b\bmod c,c,n) +2\lfloor\frac bc\rfloor f(a\bmod c,b\bmod c,c,n)+h(a\bmod c,b\bmod c,c,n)
\]
如果 \(a,b\lt c\):
\[\begin{aligned}
h(a,b,c,n)&=\sum_{i=0}^n\lfloor\frac{ai+b}c\rfloor^2 \\
&=\sum_{i=0}^n(2\sum_{j=1}^{\lfloor\frac{ai+b}c\rfloor}j-\lfloor\frac{ai+b}c\rfloor) (将平方展开成求和式) \\
&=2\sum_{j=0}^{m-1}(j+1)\sum_{i=0}^n[j\lt\lfloor\frac{ai+b}c\rfloor]-f(a,b,c,n) \\
&=2\sum_{j=0}^{m-1}(j+1)\sum_{i=0}^n[cj\lt(ai+b)-c+1]-f(a,b,c,n) \\
&=2\sum_{j=0}^{m-1}(j+1)\sum_{i=0}^n[\lfloor\frac{cj+c-b-1}a\rfloor\lt i]-f(a,b,c,n) \\
&=2\sum_{j=0}^{m-1}(j+1)(n-\lfloor\frac{cj+c-b-1}a\rfloor)-f(a,b,c,n) \\
&=2\sum_{j=0}^{m-1}(j+1)n-2\sum_{j=0}^{m-1}(j+1)\lfloor\frac{cj+c-b-1}a\rfloor-f(a,b,c,n) \\
&=2n\frac{m(m+1)}2-2\sum_{j=0}^{m-1}j\lfloor\frac{cj+c-b-1}a\rfloor-2\sum_{j=0}^{m-1}\lfloor\frac{cj+c-b-1}a\rfloor-f(a,b,c,n) \\
&=nm(m+1)-2g(c,c-b-1,a,m-1)-2f(c,c-b-1,a,m-1)-f(a,b,c,n)
\end{aligned}\]
递归时需要用到 \(f\) 和 \(g\)。
发现三个式子可以互相递归,并且每一个 \(𝑓/𝑔/ℎ(𝑎,𝑏,𝑐,𝑛)\) 仅与 \(𝑓/𝑔/ℎ(𝑐,𝑐−𝑏−1,𝑎,𝑚−1)\) 有关, 但\(ℎ(𝑎,𝑏,𝑐,𝑛)\) 不是。
因此我们不妨直接计算 \(𝑓/𝑔/ℎ(𝑐,𝑐−𝑏−1,𝑎,𝑚−1)\),然后计算出 \(𝑓/𝑔/ℎ(𝑎,𝑏,𝑐,𝑛)\)。
代码:
/*
* @Author: zhaoyang.liang
* @Github: https://github.com/LzyRapx
* @Date: 2019-10-23 23:02:12
*/
#include <bits/stdc++.h>
#define mod 1000000007
using namespace std;
typedef long long ll;
ll inv2, inv6;
ll a, b, c, l, r;
struct E {
ll f, g, h;
E() {}
E(ll _f, ll _g, ll _h) { f = _f, g = _g, h = _h; }
};
ll qpower(ll a, ll b) {
ll res = 1;
while (b > 0) {
if (b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
// f:\sum_{i=0}^{n}\lfloor\frac{ai+b}{c}\rfloor
// g:\sum_{i=0}^{n}i\times\lfloor\frac{ai+b}{c}\rfloor
// h:\sum_{i=0}^{n}\lfloor\frac{ai+b}{c}\rfloor^{2}
E calc(ll a, ll b, ll c, ll n) {
if (!a) return E(0, 0, 0);
E x, y;
if (a >= c || b >= c) {
x = cal(a % c, b % c, c, n);
y.f = (a / c * n % mod * (n + 1) % mod * inv2 + b / c * (n + 1) + x.f) % mod;
y.g = (a / c * n % mod * (n + 1) % mod * (n * 2 + 1) % mod * inv6 +
b / c * (n + 1) % mod * n % mod * inv2 + x.g) % mod;
y.h = a / c * (a / c) % mod * n % mod * (n + 1) % mod * (n * 2 + 1) % mod * inv6 % mod;
(y.h += b / c * (b / c) % mod * (n + 1)) %= mod;
(y.h += a / c * (b / c) % mod * n % mod * (n + 1)) %= mod;
(y.h += 2LL * (a / c) % mod * x.g) %= mod;
(y.h += 2LL * (b / c) % mod * x.f) %= mod;
y.f = (y.f + mod) % mod;
y.g = (y.g + mod) % mod;
y.h = (y.h + mod) % mod;
return y;
}
ll m = (a * n + b) / c;
x = calc(c, c - b - 1, a, m - 1);
y.f = (n * m - x.f) % mod;
y.g = y.g * inv2 % mod;
y.h = (n * m % mod * (m + 1) - 2LL * x.g - 2LL * x.f - y.f) % mod;
y.f = (y.f + mod) % mod;
y.g = (y.g + mod) % mod;
y.h = (y.h + mod) % mod;
return y;
}
int main() {
inv2 = qpower(2, mod - 2);
inv6 = qpower(6, mod - 2);
// do something
return 0;
}