1. 程式人生 > >Uva1363(余數性質/減少枚舉量)

Uva1363(余數性質/減少枚舉量)

typedef 直接 a13 整數 %d std 余數 \n uva

題意:

輸入正整數n和k(範圍均為1e9),求∑(k mod i),i從1~n

解法:

首先這道題直接暴力親測會超時。

之後我們寫幾組數據之後可以發現當k/i的商相同的時候他們的余數成一個等差數列,而且數列首相是q,公差是p,項的個數是余數/商。

具體寫法網上面有分情況討論的,但是較為繁瑣,這裏LRJ的板子感覺寫法就很精煉。

我們從左到右依次枚舉每一項i(核心思想是減少i的枚舉個數),計算出k除以這個數的商和余數, 如果這個商是0,說明此時的i已經大於k;如果不為0(即大於0),即來計算等差的數列的值。

如果k%i==0,則項的個數為0,計算和之後為0,其他情況就很正常了。

 1 #include<cstdio>
 2
#include<algorithm> 3 using namespace std; 4 typedef long long ll; 5 ll series_sum(int p, int d, int n) { return (ll)(2 * p - n*d)*(n + 1) / 2; } 6 int main() { 7 int n, k; 8 while (scanf("%d%d", &n, &k) != EOF) { 9 ll ans = 0, i = 1; 10 while (i <= n) {
11 int p = k / i, q = k%i; 12 int cnt = n - i; 13 if (p > 0)cnt = min(cnt, q / p);//計算項的個數,避免超出n的範圍 14 ans += series_sum(q, p, cnt); 15 i += cnt + 1; 16 } 17 printf("%lld\n", ans); 18 } 19 return 0; 20 }

Uva1363(余數性質/減少枚舉量)