题意:给出d,n,求d/1+d/2+……+d/n,所有除法向上取整。
分析:我们从两边同时计算,算d/i时,同时算出由面所有d/x等于i的项的和,直到两端汇合。
这些x中的一个应该是minx = d/i向上取整,因为minx*i>=d且(minx-1)*i<d,所以d/minx<=i且d/(minx-1)>i。也就是说minx再小一点那么d/minx向上取整的结果就会比i大。
复杂度为sqrt(n)。
View Code
#include#include #include #include using namespace std; long long d, n; long long ans; void work() { long long e = n + 1, s = n + 1; long long i = 1; ans = 0; while (s != 1 && s > i && i <= n) { s = (d - 1) / i + 1; if (s < e) { ans += (e - s) * i; e = s; } if (s > i) ans += s; i++; } printf("%lld\n", ans); } int main() { //freopen("t.txt", "r", stdin); while (scanf("%lld%lld", &d, &n), n | d) // for (d = 1; d < 50; d++) // for (n = 1; n < 50; n++) { work(); // long long ans1 = 0; // for (int i = 1; i <= n; i++) // ans1 += (d - 1) / i + 1; // if (ans1 != ans) // { // cout << "al;skdjflasjdflkj" << endl; // cout << n << " " << d << endl; // } // printf("%lld\n", ans1); } return 0; }