万能欧几里得

这个目前网上好像没有详细的教程,我来造福社会吧。

为了方便本文的叙述,做一个不严谨的规定。在本文中一个\(01\)串可以对应一些信息,并且这些信息是支持合并的,即如果用\(g(S)\)表示\(01\)\(S\)对应的信息,那么可以用\(g(S)\)\(g(T)\)计算出\(g(S+T)\)。因此我们不妨类比字符串,将这类信息的合并看作是加法。同样的,这类信息与数字的乘法代表连续的合并。

万能欧几里得可以解决基本所有的类欧几里得问题,而且不同的问题不需要重新推式子,只需要稍作修改即可。

首先来形式化的说明一下万能欧几里得能解决的问题:

给定\(p,q,r,l\)以及\(g('0')\)\(g('1')\),并给出一种信息合并的方式满足\(g(S)+g(T)=g(S+T)\)。从左至右考虑函数\(y=\frac{px+r}{q}\)\((0,l]\)内的直线并维护一个\(01\)字符串\(S\),每当和\(x=c\)\(c\)是整数)相交时在\(S\)的末尾添加\('0'\),每当和\(y=c\)\(c\)是整数)相交时在\(S\)的末尾添加\('1'\),当经过整点时先添加\('1'\)后添加\('0'\)。求\(01\)\(S\)所对应的信息。

可以发现类欧几里得问题都可以转化为上述问题。举个例子,如果我们要求:

\[\sum_{i=0}^li\lfloor\frac{pi+r}{q}\rfloor\]

那么从结果上来讲我们只需要知道每个串对应的\(\sum i\lfloor\frac{pi+r}{q}\rfloor\),考虑对两个串进行合并,那么对于后面的串来讲\(\sum i\lfloor\frac{pi+r}{q}\rfloor\)就变成了\(\sum (i+x)(\lfloor\frac{pi+r}{q}\rfloor+y)\),其中\(x\)\(y\)分别是前面的串中\(i\)\(\lfloor\frac{pi+r}{q}\rfloor\)最终的值。那么显然为了合并\(x\)\(y\)也是需要维护的。

进一步考虑\(\sum (i+x)(\lfloor\frac{pi+r}{q}\rfloor+y)=(\sum i\lfloor\frac{pi+r}{q}\rfloor)+(x\sum\lfloor\frac{pi+r}{q}\rfloor)+(y\sum i)+(xy\sum 1)\),考虑到\(\sum i\)\(\sum 1\)都可以由后面的串的\(x\)直接得到因此无需维护,只需要再对\(\sum\lfloor\frac{pi+r}{q}\rfloor\)进行维护即可。维护的计算方式稍加推导即可得知。

我们将解决上述问题的方法表示为\(f(p,q,r,l,s_0,s_1)\)(其中\(s_0\)\(s_1\)分别表示\(g('0')\)\(g('1')\)),考虑如何递归至更小的规模:

首先可以发现,我们将\(r\)\(q\)取余是没有关系的(因为\(S\)不会改变),于是可以保证\(r<q\)

接着,如果\(p<q\)考虑如何转化为\(p\geq q\)。发现这或许可以通过将坐标系的横纵轴翻转解决。我们设\(k=\lfloor\frac{pl+r}{q}\rfloor\),那么可以考虑先处理好值域在\((1,k]\)之间的部分。如果\(k=0\),那么不会经过\(y=c\),我们直接返回\(s_0*l\)。否则我们将坐标轴反转并平移,可以使之前的问题等价于函数\(y=\frac{qx+(q-r)}{p}\)\((0,k-1]\)之间的部分,此时我们需要将\(s_0\)\(s_1\)互换。不过这里有一个问题是互换了\(s_0\)\(s_1\)以后,如果经过了整点那么实际的顺序会与我们规定的相反,为了解决这个问题,我们将函数整体向下平移\(\frac{1}{p}\),即变成\(y=\frac{qx+(q-r-1)}{p}\),那么原来的经过整点就变成了先与\(x=c\)相交的情况,和我们期望的一致,并且对其它的经过方式都不会产生结果上的变化。当然这会对头尾的需要单独处理的一小部分产生一些影响,接下来会说明这个问题。现在我们可以递归到\(f(q,p,q-r-1,s_1,s_0)\)

接下来还需要处理首尾的问题。先考虑开头,由于我们已经处理了值域在\(1\)之后的,那么与\(y=c\)相交的情况只会出现一次,于是我们统计与\(x=c\)相交的次数,那么就是函数与\(y=1\)相交的点的横坐标的下取整即\(\lfloor\frac{q-r}{p}\rfloor\)。不过需要特别注意的是当\(\frac{q-r}{p}\)为整数时,我们经过了\((1,\frac{q-r}{p})\)这个整点,而由于我们之前将递归的函数下移了\(\frac{1}{p}\),因此递归的部分实际上会将与\(x=\frac{q-r}{p}\)相交的情况包含,因此我们在开头需要计算的与\(x=c\)相交的次数只有\(\lfloor\frac{q-r-1}{p}\rfloor\)次,之后再与\(y=1\)相交。即,在开头需要额外添加的信息是\(s_0*{\lfloor\frac{q-r-1}{p}\rfloor}+s_1\)

尾部的问题也是类似的。由于函数值的整数部分不会再增加,于是只有与\(x=c\)相交的情况。计算可得与\(y=k\)相交的点横坐标为\(\frac{kq-r}{p}\),由于递归下去的函数平移了\(\frac{1}{p}\)因此我们实际上只处理到了\(\frac{kq-r-1}{p}\),于是我们在末尾加上\(s_0*({l-\lfloor\frac{kq-r-1}{p}\rfloor})\)即可。

于是我们可以保证\(p\geq q\),考虑怎么解决这一部分。

我们设\(k=\lfloor\frac{p}{q}\rfloor\),那么原函数可以表示为\(y=kx+\frac{(p\ \bmod\ q)x+r}{q}\),将其与函数\(y=\frac{(p\ \bmod\ q)x+r}{q}\)相比,相当于在每次经过\(x=c\)之前额外经过\(k\)\(y=c\)。于是我们可以递归至\(f(p\bmod q,q,r,l,s_1*k+s_0,s_1)\)

综上所述,我们完整的解决了万能欧几里得问题。为了使思路更加清晰,我们用伪代码的形式重新整理一遍之前的方法。

\(f(p,q,r,l,s_0,s_1)\)
\(\ \ \ \ r=r\bmod q\)
\(\ \ \ \ \text{if}\ p<q\ \text{then}\)
\(\ \ \ \ \ \ \ \ k=\lfloor\frac{pl+r}{q}\rfloor\)
\(\ \ \ \ \ \ \ \ \text{if}\ k=0\ \text{then}\)
\(\ \ \ \ \ \ \ \ \ \ \ \ \text{return}\ s_0*l\)
\(\ \ \ \ \ \ \ \ \text{return}\ s_0*{\lfloor\frac{q-r-1}{p}\rfloor}+s_1+f(q,p,q-r-1,k-1,s_1,s_0)+s_0*(l-\lfloor\frac{kq-r-1}{p}\rfloor)\)
\(\ \ \ \ \text{else}\)
\(\ \ \ \ \ \ \ \ k=\lfloor\frac{p}{q}\rfloor\)
\(\ \ \ \ \ \ \ \ \text{return}\ f(p\bmod q,q,r,l,s_1*k+s_0,s_1)\)

如果将维护信息的加法和乘法的复杂度看作\(O(1)\),那么万能欧几里得的复杂度与欧几里得算法的分析相似,为\(O(\log n)\)。值得注意的是通常为了方便乘法可以用倍增进行快速乘,不过如果分析系数与乘数的关系可以得到更快的方法。

\(P.S.\)用平移\(\frac{1}{p}\)的方式处理特殊要求的方法是嘿嘿嘿同学告诉我的,嘿嘿嘿太强了。

转载于:https://www.cnblogs.com/Mr-Spade/p/10370259.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值