由于博主很菜,在这里只想简单推导两个最经典的问题模型用类欧的做法。
这两个模型的扩展等哪天有梦想了再补吧。。。
Part 1
求
∑i=0n⌊ai+bc⌋
设答案为函数f(a,b,c,n)
当a>=c或b>=c的时候,我们可以提出一个⌊ac⌋或⌊bc⌋,从而转移到f(a%c,b%c,c,n)
考虑这条式子的几何意义,我们可以发现它表示一条直线下面的整点的数目
设m=⌊an+bc⌋即顶点,我们可以转化一下式子
∑i=0n∑j=1m[⌊ai+bc⌋≥j]
∑i=0n∑j=1m[ai+bc≥j]
∑i=0n∑j=0m−1[ai+bc≥j+1]
考虑真值表达式里面的值
ai+bc≥j+1
ai+b≥cj+c
ai>cj+c−b−1
i>⌊cj+c−b−1a⌋
代回原式
∑i=0n∑j=0m−1[i>⌊cj+c−b−1a⌋]
重新考虑它的几何意义,可以发现这表示这条直线之上的点数
∑j=0m−1n−⌊cj+c−b−1a⌋
nm−∑j=0m−1⌊cj+c−b−1a⌋
nm−f(c,c−b−1,a,m−1)
观察f的第一个和第三个参数,发现这样转移的复杂度是等于欧几里得算法的复杂度的。
Part 2
求一个最小的u和v,满足
a/b<u/v<c/d
其实最小化分子和分母是一样的
那么我们可以这样考虑,如果a>=b,那么我们把不等式左右同时减去⌊ab⌋
那么就得到了一个新的不等式a′/b < u′/v < c′/d
如果这时候c’>d了那么u’,v就可以等于1了
如果不行那么我们就把不等式翻过来变成d/c′ < v/u′ < b/a′
这样递归下去进行就可以了
边界还有一个是a=0
这样每次左右减就相当于a%=b,所以复杂度也是log n