整除分塊 學習筆記

2022-05-30 17:36:07 字數 1436 閱讀 7994

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 # define 

intlong

long

using

namespace

std;

intn,k;

int calc(int n,int

k)

return

ret;

}int g(int n,int k)

signed main()

hgoi20181027模擬題:

給定n,m,快速求出 fht(n,m)% (1e9+7)的值。

對於100%的資料: n,m <= 1,000,000,000

先對式子化簡:

然後就是求一部分就行了,然後就是和上面處理方法一樣令g(n,k)中n=k就可以解決了

# include # define 

intlong

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...