poj2668
题意:给出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 <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
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;
}