[CodeForces #80 Div 1 D] 分塊+樹狀數組/線段樹

Part 1 題解

題意

給出一個長度爲N(300000) 的數列ai ,再給出M 個詢問,每個詢問是形如(x,y) 的形式,你需要輸出ax+ax+y+ax+2y+...+ax+ky 的和,其中x+(k+1)y>N

分析

PS:這道題的做法是對大小進行分塊

對於每個詢問,首先我們想到的方法是依次將axax+y ,…,ax+ky 來相加。
但是這樣會TLE。

我們應該想一下出現超時的原因,並從這方面加以改進。
超時的原因:y 可能非常的小,加的次數非常的多。

那麼我們可以設一個數T=H(n) ,即Tn 的一個函數。
對於y>T ,直接使用上述方法,時間複雜度爲O(n2T)
對於y<T ,要想出另外一種方法。

y 小帶來的特殊性就是可以存儲下來預處理而不使空間太大。
我們先預處理出ans[x][y] 表示詢問(x,y) 的答案。
具體的做法是枚舉每一個y ,然後將x 從大到小枚舉遞推答案,則有:
ans[x][y]=ans[x+y][y]+a[x]
預處理的時間複雜度爲O(nT) ,查詢一次的複雜度爲O(1)

所以總的時間複雜度爲O(nT+n2T)
nT=n2TT=n 時,取得最小值。
所以總的時間複雜度爲O(nn) ,空間複雜度爲O(nn)

Part 2 變式一

題目

給出一個長度爲N(300000) 的數列ai ,再給出M 個操作:
① A x d:將ax 加上d
② Q x y:詢問ax+ax+y+ax+2y+...+ax+ky 的和,其中x+(k+1)y>N

分析

在原題的基礎上,只需要對操作①進行維護即可。

對於操作① A x d:
首先將ax 賦值爲ax+d
然後考慮ax 的改變對於ans[i][j] 的影響。

我們枚舉j
對於相同的j ,所有k<iik 關於j 同類。都有ans[k][j] 增大了d

不屬於這個類的,統計的時候也不會用到。
那就是——區間增值?
當然可以。

我們對每個T 開一個樹狀數組,對於操作A x d,枚舉所有的類1T ,然後將這個類的前x 位都增大d 即可。

T=n 時,總的時間複雜度爲O(nnlogn)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章