万欧学习笔记

淦,学习笔记一直咕咕咕,咕的忘记咋做了/ll

已经不知道咕了几篇学习笔记了

pb 大师写的易懂博客(但是我就是要再抄一遍!)

万能欧几里得确实挺万能的,可以解决形如下述的问题(其实有缺陷):

给定一条直线 \(y=\frac{px+r}{q} \quad (p,q>0,r \ge 0)\) ,我们在 \(x\in(0,l]\) 上从左往右扫描,若当前 \(y=k \quad (k \in \mathbb{Z})\) 则给操作序列加上一个操作 \(U\) ,然后若当前 \(x=k \quad(k \in \mathbb{Z})\) 则给操作序列加个操作 \(R\)

如果操作 \(U\)\(R\) 满足结合律,那么就可以万能欧几里得

为了更好的约束问题,若 \(r \ge q\) ,则直接将多出的 \(\lfloor \frac{r}{q} \rfloor\)\(U\) 操作加在最前面,然后只需处理 \(r \bmod q\) 的问题了

我们记上面这个问题的答案操作序列为 \(solve(p,r,q,l,U,R)\) ,分为两种情况来讨论


\(p \ge q\) ,则一个 \(R\) 操作之前必然有 \(\lfloor \frac{p}{q} \rfloor\)\(U\) 操作,我们令 \(R'=U^{\lfloor \frac{p}{q} \rfloor}R\) ,然后计算 \(solve(p \bmod q,r,q,l,U,R')\) 即可

 


\(p<q\) ,我们试图将 \(p\)\(q\) 交换一下,这样就可以转换到第一步然后获得优秀的复杂度

首先把没有 \(U\) 操作的平凡情况去掉

可以发现第 \(a\)\(R\) 操作之前有 \(\lfloor \frac{pa+r}{q} \rfloor\)\(U\) 操作,如果第 \(b\)\(R\) 操作在其之后,则需满足

\[b > \lfloor \frac{pa+r}{q} \rfloor \]

推一推,我们的目的是将 \(a\)\(b\) 表示

\[b>\frac{pq+r}{q} \]

\[a<\frac{qb-r}{p} \]

\[a<\lceil \frac{qb-r}{p} \rceil \]

\[a \le \lfloor \frac{qb-r-1}{p} \rfloor \]

这样第 \(i\)\(U\) 操作前就有 \(\lfloor \frac{qi-r-1}{p} \rfloor\)\(R\) 操作了,和原问题等价...了吗?

如果这样的话 \(r'=-r-1\) ,不满足原问题的条件了!所以我们考虑把第一个 \(U\) 操作和之前的 \(R\) 操作直接处理出来,观察此时的 \(r'\)

可以发现删去之后的第 \(i\) 个与第 \(i-1\)\(U\) 操作之间有 \(\lfloor \frac{q(i+1)-r-1}{p} \rfloor-\lfloor \frac{qi-r-1}{p} \rfloor=\lfloor \frac{qi+q-r-1}{p} \rfloor-\lfloor \frac{q(i-1)+q-r-1}{p} \rfloor\)\(R\) 操作

可能觉得 \(r'=q-r-1\) ?不!因为注意到我们原本已经删除的第一个 \(U\) 操作前的 \(R\) 操作算过了,所以 \(r'=(q-r-1) \bmod p\)

然后再观察一下 \(l'\) 就是原来 \(U\) 的操作数减 \(1\) (减 \(1\) 是因为忽略了第一个 \(U\) ),也就是 \(l'=\lfloor \frac{pl+r}{q} \rfloor-1\) ,然后最后的 \(U\) 后面还剩了几个 \(R\) 需要加上,所以可以得到

\[solve(p,q,r,l,U,R)=R^{\lfloor \frac{q-r-1}{p} \rfloor}Usolve(q,r',p,l',R,U)R^{l-\lfloor \frac{q(l'+1)-r-1}{p} \rfloor} \]

 


可以发现因为有结合律,故 \(U^k\)\(R^k\) 都可以 \(O(c \log k)\) 的计算( \(O(c)\) 是合并两个操作花的时间),随便推推可以发现总复杂度为 \(O(c \log \max(p,q))\)

反正各种题的 \(solve\) 几乎没区别,贴一份通用代码(这里默认 \(r<q\) ):

点击查看代码
#define ll long long

inline ll Div(ll p,ll x,ll r,ll q){
    return ((__int128)x*p+r)/q;
}

D solve(ll p,ll r,ll q,ll l,D U,D R){
    if(!l)return D();
    if(p>=q)return solve(p%q,r,q,l,U,qmul(U,p/q)+R);
    ll lc=Div(p,l,r,q);
    if(!lc)return qmul(R,l);
    return qmul(R,(q-r-1)/p)+U+solve(q,(q-r-1)%p,p,lc-1,R,U)+qmul(R,l-Div(q,lc,-r-1,p));
}

好像大部分例题都有详细的题解了,这里就不写了

posted @ 2022-06-20 22:00  一叶知秋‘  阅读(8)  评论(0编辑  收藏  举报