P2261 CQOI2007 餘數求和

2022-03-04 05:57:38 字數 1384 閱讀 4158

數學題,無背景

給出正整數n和k,計算g(n, k)=k mod 1 + k mod 2 + k mod 3 + … + k mod n的值,其中k mod i表示k除以i的餘數。例如g(10, 5)=5 mod 1 + 5 mod 2 + 5 mod 3 + 5 mod 4 + 5 mod 5 …… + 5 mod 10=0+1+2+1+0+5+5+5+5+5=29

輸入格式:

兩個整數n k

輸出格式:

答案輸入樣例#1: 

10 5

輸出樣例#1: 

29

30%: n,k <= 1000

60%: n,k <= 10^6

100% n,k <= 10^9

solution:

本題$zyys$的數論分塊。

類似於$ahoi$約數研究的思路。

首先,對取模式子化簡得:$k\;mod\;i=k-i\times\lfloor\rfloor$。

所以最後的$ans=\sum\limits_^\rfloor)}=n\times k-\sum\limits_^\rfloor}$

對於$i\times\lfloor\rfloor$中,$\lfloor\rfloor$有許多是相同的,假設$x=\lfloor\rfloor$($i$為第一次出現$x$值的下標),則$i_=\lfloor\rfloor$,從$i$到$i_$共有$i_-i+1$個$x$。

注意到$i\times\lfloor\rfloor$中還有係數$i$,而$i$到$i_$是遞增的(每次加$1$),所以是乙個公差為$x$的等差序列,直接套上等差數列求和公式即可。

因為$i\leq n$且$\lfloor\rfloor$可能為$0$,所以記得判斷邊界。

由於$\lfloor\rfloor$的值最多有$2\times\sqrt$個,所以時間複雜度為$o(\sqrt)$。

**:

#include#define il inline

#define ll long long

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

#define bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)

#define max(a,b) ((a)>(b)?(a):(b))

#define min(a,b) ((a)>(b)?(b):(a))

using

namespace

std;

ll ans=0

,n,k;

intmain()

cout

}

P2261 CQOI2007 餘數求和

我是題面 題意還是很清晰,很容易理解 1e9範圍明顯不能暴力,除非你能把常數優化到 frac1 但我實在想象不到用了這麼多取模怎麼把常數優化下去 我們可以把 k i 變成 k k i i 整除 那麼總的和也就從 sum k i 變成了 sum n k k i i 又可以轉化為 nk sum n k ...

P2261 CQOI2007 餘數求和

數學題,無背景 給出正整數n和k,計算g n,k k mod 1 k mod 2 k mod 3 k mod n的值,其中k mod i表示k除以i的餘數。例如g 10,5 5 mod 1 5 mod 2 5 mod 3 5 mod 4 5 mod 5 5 mod 10 0 1 2 1 0 5 5 ...

P2261 CQOI2007 餘數求和

這道題看上去很簡單,暴力隨便打,30分拿到手。但是顯然你拿30分你就炸了。我們開始考慮優化。發現每乙個 都是風馬牛不相及的,我們考慮轉換。可以發現取膜的性質 a mod b a b times lfloor frac rfloor 然後這個答案就可以轉換為 sum rfloor 用乘法分配律可以把 ...