傳送門
給出正整數n和k,計算j(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值。
例如j(5, 3)=3 mod 1 + 3 mod 2 + 3 mod 3 + 3 mod 4 + 3 mod 5=0+1+0+3+3=7。
第一印象肯定是暴力了,但是本題目的資料量太大了,暴力會tle,因此需要考慮另外的解法。
k %i
=k−⌊
k/i⌋
×i
k\%i=k-\lfloor k / i \rfloor \times i
k%i=k−
⌊k/i
⌋×i,我們將每個取模運算都寫成這樣的形式,會得到,最終的結果是
n k−
∑i=1
n⌊k/
i⌋×i
nk-\sum_^\times i
nk−∑i=
1n⌊
k/i⌋
×i nknk
nk的值是直觀可見的,∑i=
1n⌊k
/i
⌋\sum_^
∑i=1n
⌊k/i
⌋就是整出分塊的內容,根據整出分塊我們可以知道,裡面有相當一部分連續的區間的值是相同的,而這些區間後續需要乘的數字(由於區間連續,所以數字是連續的)是公差為1
11的等差數列,只要確定每個區間的左右端點,就可以再o(1
)o(1)
o(1)
的時間內求解這乙個連續區間的答案,而數論分塊告訴我們,每乙個塊的起點如果是i
ii,則終點是⌊k/
⌊k/i
⌋⌋
\lfloor k/ \lfloor k/i\rfloor\rfloor
⌊k/⌊k/
i⌋⌋,但是要注意最後乙個區間的右端點可能會小於這個值,因此需要取它和n
nn的最小值。
#include
using
namespace std;
typedef
long
long ll;
ll n, k;
ll get
(ll l, ll r)
intmain()
cout << res <<
"\n"
;return0;
}
LuoguP2261 餘數求和 數論分塊
luogu 我看了一堆大佬的部落格才搞懂數論分塊 數論分塊適用於給定 n,k 求型如 sum left lfloor frac right rfloor f l,r 的式子 可將 o n 的複雜度降至 o sqrt n 首先定義 l 1,r 其次有 r min n,left lfloor frac ...
51nod 1225 餘數之和 數論
1225 餘數之和 f n n 1 n 2 n 3 n n 其中 表示mod,也就是餘數。例如f 6 6 1 6 2 6 3 6 4 6 5 6 6 0 0 0 2 1 0 3。給出n,計算f n 由於結果很大,輸出mod 1000000007的結果即可。輸入1個數n 2 n 10 12 輸出f n...
5814 餘數之和(整數分塊)
描述 給出正整數n和k,計算j n,k k mod 1 k mod 2 k mod 3 k mod n的值 其中k mod i表示k除以i的餘數。例如j 5,3 3 mod 1 3 mod 2 3 mod 3 3 mod 4 3 mod 5 0 1 0 3 3 7 輸入 輸入僅一行,包含兩個整數n,...