1. 程式人生 > >【題解】CQOI2007余數求和

【題解】CQOI2007余數求和

利用 its post () init per gpo amp max

大家都說這題水然而我好像還是調了有一會兒……不過暴力真的很良心,裸的暴力竟然還有60分。

打一張表出來,就會發現數據好像哪裏有規律的樣子,再仔細看一看,就會發現k/3~k/2為公差為2的等差數列,k/2~之後為公差為1的等差數列,於是我們就可以利用高斯求和快速求解啦。自認為代碼是能夠看得的...

#include <bits/stdc++.h>
using namespace std;
#define LL long long 
#define int long long
LL ans;
int p, x = 10, n, m, k, base, skipper; 

LL Get_sum()
//高斯求和,從p項開始公差為x { int y = x - 1; int base = (k % p); int end = max(base % y, base - (m - p) * y); skipper = ((base - end) / y) + 1; return ((LL)(base + end) * (LL)skipper) >> 1; } void init()//分段設x值 { if(k > 1000000) x = 1555; else if(k > 5000000) x = 600; else if(k > 300000
) x = 100; else if(k > 5000) x = 50; else x = 2; } signed main() { scanf("%lld%lld", &n, &k); m = min(n, k); init(); for(p = 1; p <= m; p ++) { if(p == (k / x) + 1) { ans += Get_sum(); p += (skipper - 1);//統計加了多少項 x -= 1
; } else ans += (k % p); } if(n > k) ans += (LL) (n - k) * (LL) (k); printf("%lld", ans); return 0; }

【題解】CQOI2007余數求和