首页 > 其他分享 >万能欧几里得小记

万能欧几里得小记

时间:2024-07-14 17:40:28浏览次数:10  
标签:prod frac ty 欧几里得 我们 aligned 万能 小记

类欧几里得

类欧几里得算法解决这样的问题:

\[f(p, q, r, n) = \sum_{x=0}^n[\frac{px+r}{q}] \]

可以理解为一条直线下方的整点个数。

第一步

首先,我们可以将 \(r\) 对 \(q\) 取模,从而提取出一个不变量。

第二步

我们可以继续将 \(p\) 对 \(q\) 取模,从而使得 \(p,r\) 都在 \([0, q)\) 内。

第三步

现在会发现这条直线斜率和截距小于 \(1\),于是我们考虑通过对称和割补法使得又变成一条斜率大于 \(1\) 的直线,并且规模变小,从而达到辗转相除的效果。

好了现在你已经会了类欧几里得了。

但是由于这个东西有难推,而且形式一变就要重新推,所以不如学万能欧几里得。

万能欧几里得

还是考虑上面的求和,我们不妨考虑这样一个过程。

从原点出发,能往上走就往上走,不行就往右走,边走边统计答案,什么时候走出了 \(n\) 就得出答案。

不妨设 \(y(x) = [\frac{px+r}{q}]\)。

不妨用矩阵表示,我们维护 \(v = (y, ty = \sum y(x),1)\),则我们定义两个矩阵辅助转移:

\(U\):将 \((y, ty, 1) \to (y + 1, ty, 1)\)。

\(R\):将 \((y, ty, 1) \to (y, ty + y, 1)\)。

显然有这样的线性变换,所以我们现在只用将矩阵的乘积求出来就可以了。

不妨设:

\[f(p, q, r, n, U, R) = \prod_{x=0}^nu^{y(x) - y(x-1)}R \]

其中定义 \(y(-1) = 0\)。

第一步

还是尝试 \(r\) 对 \(q\) 取模,设 \(r = r_0 + kq\),则考虑 \(y(x) - y(x-1)\) 的影响,发现除了第一项都可以抵消,所以我们得到:

\[f(p, q, r, n, U, R) = U^kf(p, q, r_0, n, U, R) \]

第二部

尝试 \(p\) 对 \(q\) 取模,设 \(p = p_0 + kq\),则我们不难发现 \(y(x + 1) - y(x) \ge k\),这意味这我们可以尝试令 \(R' = U^kR\)。

考虑第一项 \(y(0) = [\frac{r}{q}]\),由于第一步所以 \(y(0) = 0\),于是我们得到:

\[\begin{aligned} f(p,q,r,n,U,R) &= R\prod_{x=1}^nU^{y(x) - y(x-1)-k}R'\\ &= R\prod_{x=0}^{n-1}U^{y(x+1) - y(x) - k}R'\\ &= R\prod_{x=0}^{n-1}U^{y'(x) - y'(x-1)}R'\\ \end{aligned} \]

现在在于找到合适的 \(y'(x)\),根据条件可以得到:

\[\begin{aligned} y'(x) &= y(x+1) - k(x+1)\\ &= [\frac{px+p+r - qk(x+1)}{q}]\\ &= [\frac{p_0x + p + r - qk}{q}]\\ &= [\frac{p_0x + p_0 + r}{q}] \end{aligned} \]

所以最终我们得到:

\[f(p, q, r, n, U, R) = R f(p_0, q, p_0 + r, n - 1, U, U^kR) \]

第三步

最关键的一步:如何辗转相除?

根据类欧的结论,我们现在是一条斜率截距均小于 1 的直线,这意味这 \(x\) 要比 \(y\) 多。

也就是最终的式子中,\(U\) 的个数更少,而我们现在是通过枚举 \(R\),来计算 \(U\)。所以我们现在通过枚举 \(U\) 然后计算 \(R\) 从而实现规模的减少。

不难发现,现在总共有 \(m = [\frac{pn+r}{q}]\) 个 \(U\),设 \(g(i)\) 表示第 \(i\) 个 \(U\) 的左边 \(R\) 的个数(其实所谓的 \(y(x)\) 和 \(g(i)\) 意义是相同的),则:

\[\begin{aligned} g(i) &= \sum_{x=0}^n[R_x \text{在} U_i \text{左边} ]\\ &= \sum_{x=0}^n[i \ge y(x)]\\ &= [\frac{qi + (q-1) - r + p}{p}] \end{aligned} \]

所以现在我们再去计算就会得到:

\[\begin{aligned} f(p, q, r, n, U, R) &= (\prod_{y = 0}^{m-1}R^{g(y) - g(y-1)}U)R^{n + 1 - g(m - 1)}\\ &= (\prod_{y = 0}^{m-1}R^{g(y) - g(y-1)}U)R^{n - [\frac{qm - r - 1}{p}]}\\ \end{aligned} \]

所以我们终于得到:

\[f(p, q, r, n, U, R) = f(q, p, p + q - r - 1, m - 1, R, U)R^{n - [\frac{qm - r - 1}{q}]} \]

于是我们就完成了关键的三步。

时间复杂度

首先辗转相除的时间复杂度是 \(\log \max(p,q)\),但是我们算一些矩阵的乘法快速幂会不会导致复杂升高?

不会,因为每次都是类似 \(\log(\frac{p_1}{p_2})\) 的时间,将所有的对数展开可以一一抵消。

所以现在就是 \(O(T \log \max(p, q))\),其中 \(T\) 是矩阵乘法的常数。

更进一步

我们发现,矩阵只是一个幌子,只要像线段树一样满足结合律的运算都可以,所以我们其实写一个结构题并重新定义乘法即可。

万能欧几里得的本质是计算 \(UR\) 的成绩,这意味着我们可以随便定义 \(UR\),对于所有类似的问题都可以做,且代码主题保持不变。

标签:prod,frac,ty,欧几里得,我们,aligned,万能,小记
From: https://www.cnblogs.com/rlc202204/p/18301810

相关文章

  • 拓展欧几里得算法
    877.扩展欧几里得算法-AcWing题库878.线性同余方程-AcWing题库#include<bits/stdc++.h>usingnamespacestd;intexgcd(inta,intb,int&x,int&y){if(!b){x=1,y=0;returna;}else{intt=exgcd(b,a%b,y,x);......
  • 万能可调用对象绑定器CPBind
    背景作为一个C++程序员,经常喜欢写一些代码小工具,有一天写代码用到了std::bind,需要和std::function配合使用,并且需要传递的参数类型也已经固定,所以我就想能不能写一个类让它可以接受任意类型的可调用对象(C函数,成员函数,静态函数,lambda表达式,重载operator()的类对象等),所以写出......
  • 扩展欧几里得详解——同余方程
    对于同余方程的话就是一个经典扩展欧几里得求逆元的题目。这个可以转换成,我们需要求的只是x和k从而得到一组解。通常我们会得到a和b两个元素,假设a是7,b为40,通过扩展欧几里得进行运算。这时也就是,我们第一步先开始从a,b两个数字里找到最大的那个在这里的话是40,然后利用大的......
  • 温故而知新之burp升级小记
    个人记录贴。本文仅作为技术交流使用,如有违反行为本文作者概不负责。最近突然想升级一下burpsuite,看看有啥新功能没。挺久没升级了。结果发现burp无法正常抓包,于是有了以下内容。本文内容参考链接:https://blog.csdn.net/qq_44159028/article/details/116043520升级burp详情......
  • Miller-Rabin 和 Pollard-Rho 小记
    Miller-Rabin可以帮助我们快速判断一个大数是不是质数,现在已经有了确定性算法。在\(2^{64}\)范围内,我们可以快速地进行确定性判素。二次校验定理:若\(p\)为奇质数,则\(a^x\equiv1\pmodp\)的解为\(x=±1\)。我们有这样的流程:令\(d=p-1\),然后不断检验\(a^d\)......
  • min25 小记
    min25筛可以处理这样一类问题:求$F(x)$的前缀和,其中$F(x)$是积性函数,且可以表示成$F(p)=p^a+p^b+...$这样的形式,其中$p$是质数。如果$F(p)$是多项式,我们把它们拆开分别算,然后加起来。我们希望先求出其质数位置上的值,设$g(i,j)$为$[2,i]$中,删去了$p_1$到......
  • MTT 小记
    有的时候,我们想要让多项式乘法结果中的系数,对一些不是那么常规的模数取模,或者对任意质数\(p\)取模,这时候我们可以用MTT来解决。MTT有两种,一种是三模数NTT,另一种是拆系数FFT。三模数NTT三模数NTT就是,选择三个著名的NTT模数,比如998244353、1004535809、469762049,......
  • IDEA Database DataGrip关于Hive连接驱动万能问题详解。。
    问题:默认下载的Hive驱动版本是3的,如果使用最新的3版本连接2版本的Hive会报错,报各种依赖问题。解决方案:需要下载对应版本的Hive驱动hive-jdbchadoop-common也需下载(版本不需要太严格,2和3版本都可)配置刚刚下载的依赖包(在弹出的finder文件位置,新建一个文件夹,文件夹的名称修改......
  • 【python小记】使用openpyxl库在同一个工作表下复制单元格(包括它们的值、样式和合并属
    fromopenpyxlimportload_workbook#加载工作簿和工作表wb=load_workbook('test.xlsx')sheet=wb['sheet1']#定义一个函数来复制样式defcopy_style(source_cell,target_cell):ifsource_cell.has_style:target_cell.font=source_cell.font.co......
  • 六月小记
    这个月身体挺疲惫的,nemu的进度也不是特别好,到北京还需要面对租房和学校的琐事,希望7月会好起来。过去一个月在做nemu时候发现函数指针掌握的并不是特别好,索性重新复习下。函数指针声明:typedefint(*fun_ptr)(int,int);//声明一个指向同样参数、返回值的函数指针类型#inclu......