Codeforces Round #404 (Div. 2) C. Anton and Fairy Tale

原地址 http://codeforces.com/contest/785/problem/C

题目大意 谷仓里有n个谷子,有一只鸟第一天吃一粒,第二天吃两粒,依次类推,每天如果谷仓里的谷子不足n个,则有m个谷子可以补充到谷仓(谷仓里的谷子不能超出n个) 问多少天后谷仓里没有谷子。

分析 题目数据n,m高达1e18,暴力肯定会超时。考虑输入的n和m,如果n小于等于m,那么,n天前,每次谷仓都能补满,第n天,小鸟吃n粒则一定会吃完。

然后再考虑n大于m的情况,设消耗量-每日的补充量为净消耗量k。则当时间t=m+1的时候才会出现净消耗。 设出现净消耗后l天谷子里没有余粮,则有l*(l+1)/2>=n-m符合条件的最小的l。

最后的答案即为m+l.  前面的不等式可以用求根公式求根,但是题目的数据过大 求根公式中sqrt会造成精度的误差,故不考虑这种方法。所以选用2分的方法。

代码如下:

#include<iostream>
#include<cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#define MAX 1000010
using namespace std;
int main()
{
  long long n,m,k,num,x,h,l,r,mid,z;
  while(cin>>n>>m)
  {
      num=0;
    k=m;
    num+=k;
    h=n-m;
    if(n<=m)
    {
        cout<<n<<endl;
        continue;
    }
  l=1;
  r=2e9;
  while(l+1<r)
  {
      mid=(l+r)/2;
      if(mid*(mid+1)/2<=h)
       l=mid;
      else if(mid*(mid+1)/2>h)
        r=mid;
    //   cout<<"l="<<l<<endl;
   //  cout<<"r="<<r<<endl;

  }
  if(l*(l+1)/2<h)
    l++;
   z=num+l;
   cout<<z<<endl;
  }
   return 0;
}

二分的上界r 因为 mid*(mid+1)/2最大可以达到大约1e18 固取r=2e9;

  

原文地址:https://www.cnblogs.com/a249189046/p/6558341.html