Defending Castle poj2668


Description

The kingdom Eintagra is in great danger! Overwhelming enemy has surrounded the emperor's castle and once they enter, a massacre is just what is going to be. 

Now what all people in the kingdom Eintagra can rely on, is a huge catapult that can throw heavy rocks to the crowd of enemy. The catapult is so huge that it is too hard to adjust the direction it targets. So the damage it can do to the enemy is decreasing for every throw because the enemy in the targeted area are going to move away. If on the first attack it can make a certain damage, then on the second it can do only half, and 1/3 the damage on the third attack, and this holds, by estimation, that the K-th attack does 1/K damage of the first attack can do. People are optimistic so if the damage is not an integer, they round it up to the nearest bigger integer. 

Given the damage of the first attack of the catapult and the life of the catapult, people need to know how much total damage the catapult can do to the enemy. 
Input
There are multiple test cases. Each contains two positive integers D and N in a single line, where D is the damage of the first attack of the catapult, and N is its life measured by the number of attacks it can make. D and N are both positive integers and not more than 2000000000. 

Input ends with two zeros and this line should not be processed.

Output

Output a single line with an integer reporting the total damage that the catapult can do to the enemy.

Sample Input

1 1
2 3
0 0

Sample Output

1
4



题意:给出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)。


代码:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <queue>
#include <cstdio>
#include <cmath>
#include <string>
#include <stack>
#include <cctype>
using namespace std;

#define INF 0x7fffffff
#define eps 1e-12
#define MOD 10000007
#define N 200

int main()
{
    __int64 d,n;
    while(~scanf("%I64d%I64d",&d,&n),d+n)
    {
        __int64 e=n+1, s=n+1;
        __int64 i=1;
        __int64 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("%I64d\n",ans);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值