原理不难但是写起来非常复杂的东西。

我觉得讲得非常好懂的博客。   传送门

我们设

$$f(a, b, c, n) = \sum_{i = 0}^{n}\left \lfloor \frac{ai + b}{c} \right \rfloor$$

$$g(a, b, c, n) = \sum_{i = 0}^{n}i\left \lfloor \frac{ai + b}{c} \right \rfloor$$

$$h(a, b, c, n) = \sum_{i = 0}^{n}\left \lfloor \frac{ai + b}{c} \right \rfloor^2$$

先考虑一个结论

$$\left \lfloor \frac{Ax}{y} \right \rfloor = \left \lfloor \frac{A(x \mod y)}{y} \right \rfloor + A\left \lfloor \frac{x}{y} \right \rfloor$$

那么有

$$\left \lfloor \frac{ai + b}{c} \right \rfloor = \left \lfloor \frac{(a \mod c)i + (b \mod c)}{c} \right \rfloor + i\left \lfloor \frac{a}{c} \right \rfloor + \left \lfloor \frac{b}{c} \right \rfloor$$

这个东西可以把$a \geq c$ 或者$b \geq c$的情况转化成$a,b < c$的情况。

F

先看看这个比较好做的$f$。

注意到当$a \geq c$或者$b \geq c$的时候,我们可以用以上的结论把$a$或者$b$降下来,有

$$f(a, b, c, n) = \left \lfloor \frac{b}{c} \right \rfloor(n + 1) + \left \lfloor \frac{a}{c} \right \rfloor \frac{n(n + 1)}{2} + f(a \mod c, b \mod c, c, n)$$

那么当$a, b < c$的时候,有

$$f(a, b, c, n) = \sum_{i = 0}^{n}\sum_{j = 1}^{m}[\left \lfloor \frac{ai + b}{c} \right \rfloor \geq j]$$

为了方便把$\left \lfloor \frac{an + b}{c} \right \rfloor$记为$m$。

$$f(a, b, c, n) = \sum_{i = 0}^{n}\sum_{j = 0}^{m - 1}[\left \lfloor \frac{ai + b}{c} \right \rfloor \geq j + 1]$$

$$= \sum_{i = 0}^{n}\sum_{j = 0}^{m - 1}[ai \geq cj + c - b]$$

$$= \sum_{i = 0}^{n}\sum_{j = 0}^{m - 1}[ai > cj + c - b - 1]$$

$$= \sum_{i = 0}^{n}\sum_{j = 0}^{m - 1}[i > \left \lfloor \frac{cj + c - b - 1}{a} \right \rfloor]$$

注意到这时候$i$这一项可以直接算了。

$$f(a, b, c, n) = \sum_{j = 0}^{m - 1}(n -  \left \lfloor \frac{cj + c - b - 1}{a} \right \rfloor)$$

$$= nm - f(c, c - b - 1, a, m - 1)$$

比较方便。

G

按照套路先做$a \geq c$或者$b \geq c$的情况。

$$g(a, b, c, n) = \left \lfloor \frac{b}{c} \right \rfloor\frac{n(n + 1)}{2} + \left \lfloor \frac{a}{c} \right \rfloor \frac{n(n + 1)(2n + 1)}{6}  + g(a \mod c, b \mod c, c, n)$$

然后接着按照上述套路弄$a, b < c$的情况。

$$g(a, b, c, n) = \sum_{j = 0}^{m - 1}\frac{(n - \left \lfloor \frac{cj + c - b - 1}{a} \right \rfloor)(n + 1 + \left \lfloor \frac{cj + c - b - 1}{a} \right \rfloor)}{2}$$

$$= \frac{1}{2}(mn(n + 1) - f(c, c - b - 1, a, m - 1) - h(c, c - b - 1, a, m - 1))$$

还要解决$h$。

H

当$a \geq c$或者$b \geq c$的时候

$$h(a, b, c, n) = (n + 1)\left \lfloor \frac{b}{c} \right \rfloor^2 + \frac{n(n + 1)(2n + 1)}{6}\left \lfloor \frac{a}{c} \right \rfloor^2 + n(n + 1)\left \lfloor \frac{b}{c} \right \rfloor\left \lfloor \frac{a}{c} \right \rfloor + h(a \mod c, b \mod c, c, n) + 2\left \lfloor \frac{a}{c} \right \rfloor g(a \mod c, b \mod c, c, n) + 2\left \lfloor \frac{b}{c} \right \rfloor f(a \mod c, b \mod c, c, n)$$

好麻烦啊……

当$a, b < c$的时候需要一些操作

$$n^2 = 2 \times \frac{n(n + 1)}{2} - n = 2\sum_{i = 1}^{n}i - n$$

可以得到

$$h(a, b, c, n) = \sum_{i = 0}^{n}(2\sum_{j = 1}^{\left \lfloor \frac{ai + b}{c} \right \rfloor}j - \left \lfloor \frac{ai + b}{c} \right \rfloor)$$

$$= 2\sum_{i = 0}^{n}\sum_{j = 1}^{\left \lfloor \frac{ai + b}{c} \right \rfloor}j - f(a, b, c, n)$$

$$= 2\sum_{j = 0}^{m - 1}(j + 1)\sum_{i = 0}^{n}[\left \lfloor \frac{ai + b}{c} \right \rfloor \geq j + 1] - f(a, b, c, n)$$

$$= 2\sum_{j = 0}^{m - 1}(j + 1)(n - \left \lfloor \frac{cj + c - b - 1}{a} \right \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)$$

大概就是这样了。

在计算的时候如果只考虑$(a, c)$这两项的话相当于每一次把$(a, c)$变成了$(c, a \% c)$,所以时间复杂度和欧几里得算法相同,递归层数是$log$层。

时间复杂度$O(Tlogn)$。

因为递归的式子很一致,在计算的时候应当三个东西一起算比较快。

Code:

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll; const ll P = 998244353LL; template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for (; ch > ''|| ch < ''; ch = getchar())
if (ch == '-') op = -;
for (; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} template <typename T>
inline void inc(T &x, T y) {
x += y;
if (x >= P) x -= P;
} template <typename T>
inline void sub(T &x, T y) {
x -= y;
if (x < ) x += P;
} inline ll fpow(ll x, ll y) {
ll res = ;
for (; y > ; y >>= ) {
if (y & ) res = res * x % P;
x = x * x % P;
}
return res;
} namespace Likegcd {
struct Node {
ll f, g, h;
}; #define f(now) now.f
#define g(now) now.g
#define h(now) now.h const ll inv2 = fpow(, P - );
const ll inv6 = fpow(, P - ); inline Node solve(ll a, ll b, ll c, ll n) {
Node res;
if (!a) {
f(res) = (b / c) * (n + ) % P;
g(res) = (b / c) * (n + ) % P * n % P * inv2 % P;
h(res) = (b / c) * (b / c) % P * (n + ) % P;
return res;
} f(res) = g(res) = h(res) = ;
if (a >= c || b >= c) {
Node tmp = solve(a % c, b % c, c, n);
inc(f(res), (a / c) * n % P * (n + ) % P * inv2 % P);
inc(f(res), (b / c) * (n + ) % P);
inc(f(res), f(tmp)); inc(g(res), (a / c) * n % P * (n + ) % P * (( * n + ) % P) % P * inv6 % P);
inc(g(res), (b / c) * n % P * (n + ) % P * inv2 % P);
inc(g(res), g(tmp)); inc(h(res), (a / c) * (a / c) % P * n % P * (n + ) % P * (( * n + ) % P) % P * inv6 % P);
inc(h(res), (b / c) * (b / c) % P * (n + ) % P);
inc(h(res), (a / c) * (b / c) % P * n % P * (n + ) % P);
inc(h(res), h(tmp));
inc(h(res), 2LL * (a / c) % P * g(tmp) % P);
inc(h(res), 2LL * (b / c) % P * f(tmp) % P); return res;
} if (a < c && b < c) {
ll m = (a * n + b) / c;
Node tmp = solve(c, c - b - , a, m - ); f(res) = n * m % P;
sub(f(res), f(tmp)); g(res) = n * (n + ) % P * m % P;
sub(g(res), f(tmp));
sub(g(res), h(tmp));
g(res) = g(res) * inv2 % P; h(res) = n * m % P * (m + ) % P;
sub(h(res), 2LL * g(tmp) % P);
sub(h(res), 2LL * f(tmp) % P);
sub(h(res), f(res)); return res;
} return res;
} } int main() {
int testCase;
read(testCase);
for (ll a, b, c, n; testCase--; ) {
read(n), read(a), read(b), read(c);
Likegcd :: Node ans = Likegcd :: solve(a, b, c, n);
printf("%lld %lld %lld\n", ans.f, ans.h, ans.g);
}
return ;
}

Luogu 5170 【模板】类欧几里得算法的更多相关文章

  1. Solution -「Luogu 5170」类欧几里得算法

    推柿子大赛了属于是. 题目要求三个柿子,不妨分别记为: \[\begin {align} f (a, b, c, n) &= \sum \limits _{i = 0} ^{n} \lfloo ...

  2. [P5170] 类欧几里得算法

    "类欧几里得算法"第二题 P5170 [题意]已知\(n,a,b,c\),求 \[ \begin{aligned} f_{1}(a,b,c,n)&=\sum_{i=0}^n ...

  3. 模板——扩展欧几里得算法(求ax+by=gcd的解)

    Bryce1010模板 /**** *扩展欧几里得算法 *返回d=gcd(a,b),和对应等式ax+by=d中的x,y */ long long extend_gcd(long long a,long ...

  4. LOJ138 类欧几里得算法

    类欧几里得算法 给出 \(T\) 组询问,每组用 \(n, a, b, c, k_1, k_2\) 来描述.对于每组询问,请你求出 \[ \sum_{x = 0} ^ {n} x ^ {k_1} {\ ...

  5. Solution -「LOJ #138」「模板」类欧几里得算法

    \(\mathcal{Description}\)   Link.   \(T\) 组询问,每次给出 \(n,a,b,c,k_1,k_2\),求 \[\sum_{x=0}^nx^{k_1}\left\ ...

  6. BZOJ3817 Sum(类欧几里得算法)

    设$t=\sqrt r$,原题转化为$\sum_{x=1}^n(4*\lfloor\frac{tx}2\rfloor-2*\lfloor tx\rfloor+1)$考虑如何求$\sum_{x=1}^n ...

  7. 洛谷P5170 【模板】类欧几里得算法(数论)

    传送门 此题剧毒,公式恐惧症患者请直接转去代码→_→ 前置芝士 基本数论芝士 题解 本题就是要我们求三个函数的值 \[f(a,b,c,n)=\sum_{i=0}^n \left\lfloor\frac ...

  8. [BZOJ2987]Earthquake:类欧几里得算法

    分析 类欧的式子到底是谁推的啊怎么这么神仙啊orz! 简单说一下这道题,题目中的约束条件可以转化为: \[ y \leq \frac{c-ax}{b} \] 有负数怎么办啊?转化一下: \[ y \l ...

  9. 【LuoguP4433】[COCI2009-2010#1] ALADIN(含类欧几里得算法推导)

    题目链接 题意简述 区间赋值模意义下等差数列,询问区间和 \(N\leq 10^9,Q\leq 10^5\) Sol 每次操作就是把操作区间\([L,R]\)中的数赋值成: \[(X-L+1)*A\ ...

随机推荐

  1. 集合(List、Set、Map)

    List,Set是继承自Collection接口,Map不是 public interface List<E> extends Collection<E> { public i ...

  2. streamsets 错误记录处理

    我们可以在stage 级别,或者piepline 级别进行error 处理配置 pipeline的错误记录处理 discard(丢踢) send response to Origin pipeline ...

  3. OPENQUERY用法以及使用需要注意的地方

    对给定的链接服务器执行指定的传递查询.该服务器是 OLE DB 数据源.OPENQUERY 可以在查询的 FROM 子句中引用,就好象它是一个表名.OPENQUERY 也可以作为 INSERT.UPD ...

  4. macOS -- Mac系统如何编辑hosts文件

    Hosts是一个没有扩展名的系统文件,其作用就是将一些常用的网址域名与其对应的IP地址建立一个关联"数据库",当用户在浏览器中输入一个需要登录的网址时,系统会首先自动从Hosts文 ...

  5. am335x_y蜂鸣器驱动

    修改文件:1.板级文件/arch/arm/mach-omap2/board-am335xevm.c static struct platform_device buzzer_device= { .na ...

  6. LogHelp 日记分天记录,只记30天日记

    using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...

  7. 解决:win8.1 oepnvpn客户端 redirect-gateway def1无效,自动获取的IP没有网关问题

    解决:win8.1 oepnvpn客户端 redirect-gateway def1无效,自动获取的IP没有网关问题 该问题是操作系统权限问题,需要将程序设置为以管理员模式运行和以windows7兼容 ...

  8. 冒泡排序算法-Python实现

    #-*- coding: UTF-8 -*- import numpy as np def BubbleSort(a): for i in xrange(0, a.size): for j in xr ...

  9. Makefile之自动变量篇

    自动变量假设您编写一个编译‘.c’文件生成‘.o’文件的规则:您怎样编写命令‘CC’,使它能够操作正确的文件名?您当然不能将文件名直接写进命令中,因为每次使用隐含规则操作的文件名都不一样. 您应该使用 ...

  10. FastDFS简介和安装

    FastDFS是一个轻量级的开源分布式文件系统 FastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡 FastDFS实现了软件方式的RAID,可以使用廉价的IDE硬盘进 ...