數學題,無背景
給出正整數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 用乘法分配律可以把 ...