1 条题解
-
0
luogu
#include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdio> #include<cmath> using namespace std; typedef long long ll; ll l=1,r=1e14; ll n,k,mid,ans; ll Hp[500003],num[500003]; bool check(ll p) { ll over=(ll)sqrt(p)+1;//溅射范围 ll cnt=0;//子弹放置总个数 memset(num,0,sizeof(num)); ll plus=0,i=0,i2=0; //plus表示有效子弹的个数,i表示放置子弹的位置,i2表示i^2 for(ll j=n;j>=1;j--) { if(num[j+1])//累加子弹的个数 { plus+=num[j+1]; i+=num[j+1]*(j+1); i2+=num[j+1]*(j+1)*(j+1); } if((j+over<=n)&&(num[j+over]))//删除无效子弹的个数 { plus-=num[j+over]; i-=num[j+over]*(j+over); i2-=num[j+over]*(j+over)*(j+over); } ll allhurt=1ll*plus*p-1ll*j*j*plus+2ll*i*j-i2;//计算总伤害 if(Hp[j]>=allhurt)//如果不能直接杀死 { num[j]=(Hp[j]-allhurt)/p+1; cnt+=num[j];//累加总放置子弹的个数 } if(cnt>k) return false;//如果放置子弹多余要求子弹个数 } return true;//如果小于要求子弹个数 } int main() { cin>>n>>k; for(ll i=1;i<=n;i++) { cin>>Hp[i]; } while(l<=r)//对p的范围进行二分操作 { mid=(l+r)>>1; if(check(mid)) { r=mid-1; ans=mid; } else l=mid+1; } printf("%lld",ans); return 0; } ///test
- 1
信息
- ID
- 484
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 6
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者