BZOJ 1257 餘數之和 整除優化

2021-09-12 12:31:34 字數 1551 閱讀 8286

給定正整數n和k,計算 (k mod 1)+(k mod 2)+…+(k mod n) 的值。1 <= n,k <= 1e9 .

首先我們可以先將式子進行轉換,kmo

di=k

−i∗⌊

k/i⌋

原式=n

∗k−∑

i=1n

i∗⌊k

/i

⌋k\ mod\ i = k - i*\lfloor k/i \rfloor \\ 原式=n*k-\sum\limits_^i*\lfloor k/i\rfloor

kmodi=

k−i∗

⌊k/i

⌋原式=

n∗k−

i=1∑

n​i∗

⌊k/i

⌋然後我們可以發現對於k來說,存在多個 i 使得 k / i 的值一樣大。例如 k = 6,則 i = 4、5、6,k / i = 1,因此我們可以對於如下公式對此進行優化。∀i∈

[x,⌊

k/⌊k

/x⌋⌋

],⌊k

/i⌋的

值都相等

\forall i\in [x,\lfloor k/\lfloor k/x\rfloor\rfloor], \ \lfloor k/i\rfloor \ 的值都相等

∀i∈[x,

⌊k/⌊

k/x⌋

⌋],⌊

k/i⌋

的值都相

等因此對於∀i∈

[1,k

]\ \forall \ i ∈ [1, k]

∀i∈[1,

k],⌊ k/

i⌋

\lfloor k/i\rfloor

⌊k/i

⌋ 最多只有 2

k2\sqrt

2k​ 個不同的值,所以我們可以處理出所有 ⌊k/

i⌋

\lfloor k/i\rfloor

⌊k/i

⌋ 不同的值,然後對於每一段求乙個等差數列和即可。

#include

#include

#include

#include

#define rep(i,a,b) for(int i = a; i <= b; i++)

#define log1(x1,x2) cout << x1 << ": " << x2 << endl;

#define log2(x1,x2,y1,y2) cout << x1 << ": " << x2 << " , " << y1 << ": " << y2 << endl;

typedef

long

long ll;

typedef

double db;

const db eps =

1e-9

;using

namespace std;

ll n,k,ans;

intmain()

printf

("%lld\n"

,ans)

;return0;

}

BZOJ1257 餘數之和,整除分塊

給出正整數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,k。1 n ...

BZOJ 1257餘數之和

給出正整數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,k。1 n ...

bzoj 1257 餘數之和sum 數學

time limit 5 sec memory limit 162 mb submit 3081 solved 1425 submit status discuss 給出正整數n和k,計算j n,k k mod 1 k mod 2 k mod 3 k mod n的值,其中k mod i表示k除以i的...