简介
希望退役之前能用到一次
另外推导过程应该没什么用吧 = =
类欧几里得算法
大概就是用来求这三个东西的算法
$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$
其中 $a,b,c,n\ge 0$ 且为整数
首先是求 $f$
如果 $a\ge c$ 或者 $b\ge c$
那么我们能够得到
$f(a,b,c,n)=\sum_{i=0}^n\lfloor\frac{(a\%c)i+b\%c}{c}\rfloor+i\lfloor\frac{a}{c}\rfloor+\lfloor\frac bc\rfloor=f(a\%c,b\%c,c,n)+\frac{n*(n+1)}{2}\lfloor\frac ac\rfloor+(n+1)\lfloor\frac bc\rfloor$
直接递归计算即可
那么剩下的情况就是 $a<c$ 并且 $b<c$ 的情况了
我们来愉快的化式子,首先令 $m=\lfloor\frac{an+b}{c}\rfloor$
由于下次 $f(c,c-b-1,a,m-1)$ 一定变成第一种方式计算,所以复杂度还是 $O(\log n)$
边界条件 $a=0$
那么现在来求 $g$
对于 $a\ge c$ 或者是 $b\ge c$ 的情况
类似讨论能够得到
$g(a,b,c,n)=\frac{n(n+1)(2n+1)}{6}\lfloor \frac ac\rfloor+\frac{n(n+1)}{2}\lfloor \frac bc\rfloor+g(a\%c,b\%c,c,n)$
对 $a<c$ 并且 $b<c$ 的情况
后面是一个等差数列,所以 $g(a,b,c,n)=\frac12\sum_{j=0}^{m-1}(n-\lfloor\frac{cj+c-b-1}{a}\rfloor)(n+\lfloor\frac{cj+c-b-1)}{a}\rfloor+1)$
化简得到 $g(a,b,c,n)=\frac{nm(n+1)}{2}-\frac 1 2f(c,c-b-1,a,m-1)-\frac 1 2h(c,c-b-1,a,m-1)$
好像还要求 $h$
那么我们现在求 $h$
对于 $a\ge c$ 或者 $b \ge c$ 的情况
类似讨论能够得到
$h(a,b,c,n)= h(a\%c,b\%c,c,n) + \frac{n(n+1)(2n+1)}{6}\lfloor \frac ac\rfloor^2+(n+1)\lfloor \frac bc\rfloor^2+2\lfloor \frac ac\rfloor g(a\%c,b\%c,c,n)+2\lfloor \frac bc\rfloor f(a\%c,b\%c,c,n)+n(n+1)\lfloor \frac ac\rfloor\lfloor \frac bc\rfloor$
注意到 $\lfloor \frac {ai+b}{c}\rfloor^2$ 不太好整
我们考虑如何将平方去掉,能够发现 $2\sum_{i=1}^ni-n=n(n+1)-n=n^2$
贴一下代码,时间复杂度均为 $O(\log n)$,默认 $a,b,c,n$ 同阶
1 | struct Likegcd { |
万能欧几里得算法
我们从类欧最经典的题目入手,考虑如何求这个东西 $\sum_{i=0}^n{\lfloor\frac{ai+b}{c}\rfloor}$
我们从 $ax+b$ 这条直线出发,如果经过一个纵坐标为整数的点,我们记录一个 $U$,如果经过一个横坐标为整数的点,我们记录一个 $R$,如果经过一个整点,即横纵坐标都是整数的点,我们先记录一个 $U$,然后在记录一个 $R$
容易发现,每次我们记录一个 $R$ 的时候,就是我们走到了一个新的整数 $i$(感觉这么理解有一点怪),然后这个时候 ${\lfloor\frac{ai+b}{c}\rfloor}$ 就是之前记录的 $L$ 的个数,也就是说这整个操作序列的答案就是每个 $R$ 前面的 $U$ 的个数的和
那么这个东西有什么用呢,我们考虑将之前的东西转换为这样三元组 $(U,R,ans)$ 分别表示 $U$ 的个数和$R$ 的个数以及答案
我们考虑三元组之间合并,容易得到 $(U,R,ans)\times (U’,R’,ans’)=(U+U’,R+R’,ans+ans’+U\times R’)$,并且这个东西是满足结合律的
现在我们考虑利用这个东西来求解 $\sum_{i=0}^n{\lfloor\frac{ai+b}{c}\rfloor}$,由于我们的算法是递归的,我们定义 $solve(a,b,c,n,A,B)$,其中 $A$ 表示遇到一个 $U$ 以后的变换,$B$ 表示遇到 $R$ 的变换
如果 $a\ge c$,那么容易得到两个 $R$ 之间一定有 $\lfloor\frac{a}{c}\rfloor$ 个连续的 $U$,所以我们将这些 $U$ 和这一个 $R$ 合并,得到 $solve(a\bmod c,b,c,A,A^{\lfloor\frac{a}{c}\rfloor}B)$
若 $a <c$,通过 一系列操作,我们能够得到
具体证明参考:https://www.luogu.com.cn/blog/ix-35/solution-p5170
可以证明时间复杂度为 $O(F\log n)$,其中 $n,a,b,c$ 同阶,$F$ 为做一次乘法的时间复杂度
1 | node calc(ll a, ll b, ll c, ll n, const node &A, const node &B) { |
知道如何求 $\sum_{i=0}^n{\lfloor\frac{ai+b}{c}\rfloor}$ 后,我们来尝试一些更加复杂的形式,例如 $\sum_{i=0}^ni{\lfloor\frac{ai+b}{c}\rfloor}$
我们尝试记录 $U$ 的数量 $x$,$R$ 的数量 $y$,${\lfloor\frac{ai+b}{c}\rfloor}$ 的和,$i$ 的和,$i{\lfloor\frac{ai+b}{c}\rfloor}$ 的和
我们发现合并的时候大概就是右边的贡献应该为 $(i+y)({\lfloor\frac{ai+b}{c}\rfloor}+x)$,我们将括号拆开即可
现在我们不妨来考虑更加一般化的形式,$\sum_{i=0}^n({\lfloor\frac{ai+b}{c}\rfloor})^{k_1}i^{k_2}$,注意到右边的贡献变为 $({\lfloor\frac{ai+b}{c}\rfloor}+x)^a(i+y)^b$,我们直接二项式展开,可以得到 $res.ans[a][b]=\sum_{i=0}^a\sum_{j=0}^{b}\binom{a}{i}\binom{b}{j}(u.x)^i(u.y)^jv.ans[a-i][b-j]$,由于我们还需要枚举 $a$ 和 $b$,所以总的时间复杂度为 $O(k^4\log n)$
例题
简要题意:求 $\sum_{i=0}^{n}A^iB^{\lfloor\frac{ai+b}{c}\rfloor}$,其中 $A$ 和 $B$ 均为 $N\times N$ 的矩阵
$a,b,c,n,\lfloor\frac{an+b}{c}\rfloor\le 10^{18},N\le 20$
简要题解:我们考虑万能欧几里得算法,我们定义三元组 $(B^x,A^y,ans)$,容易得到 $(B^x,A^y,ans)\times (B^{x’},A^{y’},ans)=(B^{x+x’},A^{y+y’},A^yansB^x)$,时间复杂度 $O(N^3\log n)$
简要题意:有 $T$ 组询问,每组询问给出 $n,a,b,c,k_1,k_2$,求 $\sum_{i=0}^n\lfloor\frac{ai+b}{c}\rfloor^{k_1}i^{k_2}$
$T=1000,n,a,b,c\le 10^9,k_1+k_2\le 10$
简要题解:考虑万欧,定义三元组 $(x,y,ans[a][b])$
容易得到转移 $res.ans[a][b]=\sum_{i=0}^a\sum_{j=0}^{b}\binom{a}{i}\binom{b}{j}(u.x)^i(u.y)^jv.ans[a-i][b-j]$,就是直接二项式展开,时间复杂度 $O(k^4\log n)$