【二分】Monster

来源:互联网 发布:淘宝贷款需要本人吗 编辑:程序博客网 时间:2024/06/08 17:48

【题目描述】

明明的手机上有这样一个游戏,有一排n个怪物,每个怪物的血量是mi。现在明明可以射出k个伤害均为p的火球射向某些怪物。当某个火球射到第i个怪物,除了这个怪物会掉血p以外,它左边的第j个怪物(j<=i),也会遭到Max(0, p - (i - j) * (i - j))的溅射伤害。当某个怪物的血量为负的时候,它就死了,但它的尸体已然存在,即其他怪物不会因为它死而改变位置。

明明想用这k 个火球消灭掉所有的怪物,但他同时希望每个火球的伤害p能尽可能的小,这样他才能完美过关。

【输入数据】

第一行两个数 n, k (1 ≤ n ≤ 50000, 1 ≤ k ≤ 100000)。

第二行n个数m1, m2, ...mn (1 ≤ mi ≤ 109), 表示每个怪物的生命值。

【输出数据】

最小的符合要求的p值。

【样例输入】

3 1

1 4 5

【样例输出】

6

【数据范围】

1 ≤ n ≤ 50000, 1 ≤ k ≤ 100000,1 ≤ mi ≤ 109

30%的数据,n ≤ 500

【代码】

#include<cstdio>#include<iostream>using namespace std;long long   qs,n,k;long long   m[50010],m1[50010],sum;bool check(long long   qs){ long long s[50010],i,j,p=k;for(i=1;i<=n;i++) s[i]=m[i];i=n;while(p&&i>0){s[i]-=qs;j=i-1;long long b=qs-(i-j)*(i-j);while(b>0&&j>0){s[j]-=b;j--;b=qs-(i-j)*(i-j);}p--;while(s[i]<0) i--;}if(i<1) return 1;else return 0;}int  main(){   freopen("monster.in","r",stdin);   freopen("monster.out","w",stdout);   cin>>n>>k;   for (long long   i=1;i<=n;i++)     { cin>>m[i];     sum=sum+m[i];}    long long   l=1,r=2147483647,an;while (l<=r){   qs=l+r>>1;    if(check(qs))  {r=qs-1;an=qs;    }else l=qs+1;}cout<<an;return 0;}


原创粉丝点击