类欧几里得

类欧几里得

简介

基础的类欧几里得有三种形式,可以用来快速求出者三种形式的值。

\[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;
}
posted @ 2019-10-23 22:27  LzyRapx  阅读(201)  评论(0编辑  收藏  举报