本質:二進制拆分(你說倍增我也沒脾氣)。然后是一個配湊。
合起來就是邊二進制拆分,邊配湊。
快速乘(其實龜速):把乘數二進制拆分。利用乘法分配率。
用途:防止爆long long
代碼:
ll qk(ll x,ll y,ll mod){ ll ret=0; while(y){ if(y&1) (ret+=x)%=mod; (x+=x)%=mod; y>>=1; } return ret; }
如果為了卡常,可以寫成這樣:
ll qk(ll x,ll y,ll mod){ ll ret=0; x%=mod;y%=mod; while(y){ if(y&1) ret=ret+x>=mod?ret+x-mod:ret+x; x=x+x>=mod?x+x-mod:x+x; y>>=1; } return ret; }
第一行必須有x%=mod,y%=mod,否則開始x,y可能很大,減一次mod不能減到mod以下。
還是錯過幾次。。。
(有時候卡這個取模還是挺有效的。)
快速冪(真的快速):把指數二進制拆分。利用:a^(x+y)=a^x*a^y
用途:各種指數運算,一般還取模。
推廣:矩陣快速冪。
代碼略。
快速冪經常與快速乘結合。log^2n也是可以接受的。
例題:
直接推式子,然后分治求等比數列,爆long long,要快速乘。
復雜度:O(log^3n)
upda:2018.10.12
你以為快速冪就這么簡單???
其實可以更有趣一些。
與其說快速冪本質是二進制拆分,不如說是進制拆分。
因為,我們可以10進制快速冪!!!
應用於高精快速冪。
因為/2是O(len)的,除法復雜度太高 。
而如果高精用10進制存儲,可以10進制快速冪!!每次干掉低位,類比於二進制下的左移和右移。
復雜度也是logn的。奇技淫巧第24條。
快速冪快嗎?很快。但是還是logn的。
如果要多次進行快速冪,那么每次logn的復雜度可能還是不能接受。
我們根據拆分的思想,如果指數在1e9范圍內,那么A^k=A^([k/1e4]*1e4+k%1e4)=A^([k/1e4]*1e4)*A^(k%1e4)
可以嘗試根號預處理。
upda:2019.1.19
延伸一下
分塊預處理,可以稱之為“光速冪”
然后塊速遞推