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;
,