#13663: 公式參考


kkmomo (kkmomo)

學校 : 不指定學校
編號 : 29247
來源 : [223.137.94.20]
最後登入時間 :
2024-06-28 12:05:12
c215. kevin 愛反轉 | From: [114.24.109.144] | 發表日期 : 2018-04-04 15:02

一開始用 bits reverse 建表 + bits count 建表改良很久,n 極限大概只能到撐到 10^8 左右

 

改成研究公式解,但不怎麼容易,要解大量的遞迴關係式,計算幾乎靠 Maplesoft 了

時間、空間複雜度皆為 O(log N)

主要解出 2 個公式如下圖,整理後其實還蠻短的:

假設函數 F(N) 為此題解,

式 (1):X( floor(log2(N)) ) = F(2^s - 1),s 為最大的整數滿足 N > 2^s - 1,也就是 sum { f( i + reverse(i)) | i >= 1  且  i 的二進位表示法的長度 < N 的二進位表示法的長度 }

式 (2):Y(i,j) 為將區間 [2^s, 2^(s+1)] 分成 2^(i+1) 等分,第 2 * j + 1 區間的總合, 每一組 i,j 可以決定一組 a,c,d,e,f,g,h,m

至於i,j 與 a,c,d,e,f,g,h,m 的關係可以,先寫個簡單的暴力解程式,列出 N <= 2^26 的解,觀察 式(1)及式(2)的 等差/等比 係數得到

 

ex: N = 45

解可折成 (1) 式 + { (2)式 } 二分法總合 = [1,31) + { [32,40) + [40, 44) + 45 }

 

P.S. 式(1)如果在 c 用pow() 函數,如果沒整理好,或是從 double 轉成 long的時機不對,在 N=10^15 時會誤差 1,因此吃了個NA,

如果改用位移 N < 8 時也會有問題,又吃個 NA,沒想到一式通用的方法,最後只好用 if-else 分兩段

 

參考

反轉 bit
https://stackoverflow.com/questions/746171/most-efficient-algorithm-for-bit-reversal-from-msb-lsb-to-lsb-msb-in-c/16994674

計算二進位中 1 的個數
https://en.wikipedia.org/wiki/Hamming_weight

 
ZeroJudge Forum