hgoi20181027模擬題:
給定n,m,快速求出 fht(n,m) % (1e9+7)的值。
對於100%的資料: n,m <= 1,000,000,000
然後為了這個問題我們去找了整除分塊的演算法:
對於g(n,k) 化簡 顯然 a%b=a-[a/b]*b
在c++中floor(a/b)=a/b 所以我們打個表來看看k/i的規律
我們發現這樣的規律:n/i的值相同的總是出現在相鄰位置!
在上面的式子中也就是說k/i這個東西是下取整的在乙個區間內是不會變的
設[k/i]=a (這裡是下取整): a<=k/i
然後參變分離:
得 : i<=k/a; i>k/(a+1)
所以在這裡我們發現了對於區間i∈[l,r]其[k/i]是乙個定值,當且僅當l=k/([k/i]+1)+1 ; r=k/[k/i],
所以這裡的區間[l,r]可以寫成: [k/(k/i+1)+1,k/(k/i) ] (這裡的/是整除,和c++中/等價)
對於這裡區間他們的floor(k/i)是一定的,唯一的是i在+1 +2 +3的遞增所以是乙個d=1的等差數列(起始值是k/i),我們只要知道左右區間就可以知道求和以後的值了
# include # definehgoi20181027模擬題:intlong
long
using
namespace
std;
intn,k;
int calc(int n,int
k)
return
ret;
}int g(int n,int k)
signed main()
給定n,m,快速求出 fht(n,m)% (1e9+7)的值。
對於100%的資料: n,m <= 1,000,000,000
先對式子化簡:
然後就是求一部分就行了,然後就是和上面處理方法一樣令g(n,k)中n=k就可以解決了
# include # defineintlong
long
using
namespace
std;
const
int mo=1e9+7
;int calc(int
n)
return (n*n%mo-ret%mo+mo)%mo;
}int fht(int n,int m)
signed main()
整除分塊學習筆記
其實一直沒有把整除分塊看成乙個演算法,只看成乙個思維。然後發現我不會思維了,於是來補一下學習筆記。看一道例題 uva11526 就是求 sum limits 我們發現很多值都是一樣的,所以可以快速計算掉。具體的,我們發現 i 到 frac 內所有數是一樣的。那麼就可以 o sqrt n 計算了。但是...
整除分塊學習筆記
假如我們要對這樣的式子進行求和 sum limits f i 如果 f i 的取值有限,只有 m 個,且對於所有的 f i x 在序列中都是連續的一段,那麼就可以進行值域分段求和。找出每個取值 x 在原序列中的第一次出現的位置 l x 和最後一次出現的位置 r x 可以在 o m 的時間內算出答案 ...
整除分塊 學習筆記
板子題 uva11526 題目大意 給定乙個 n 求 sum limits lfloor frac rfloor 其中 n 為 32 位無符號整數。顯然如果暴力求解肯定是不可行的,顯然會 tle,所以我們需要找一種複雜度更優的演算法。我們可以先令 n 10 觀察一下函式 operatorname x...