二分题目精选
二分题目精选
E - Square Price
https://www.luogu.com.cn/problem/AT_abc389_e
rating:1900
评述:
一道比较想背包,但是被数据范围卡的只能二分+贪心的二分题。一般来说,题目问什么二分什么,但是这题显然不能这样做,其中的单调性变量另有其人。
代码
#include <bits/stdc++.h>
typedef std::pair<long long, long long> pll;
typedef std::pair<int, int> pii;
using i64 = long long;
const int mod=1e9+7;
const int N = 2e5+5;
#define int long long
int n,m,ans=0;
int a[N];
bool ck(int x){
int res=0;
for(int i=1;i<=n;i++){
int cnt=(x/a[i]+1)/2;
if(cnt>=1000000000||cnt*cnt>=2e18||2e18/a[i]<cnt*cnt) return false;
res+=cnt*cnt*a[i];
if(res>m)return false;
}
return true;
}
void solve(){
std::cin>>n>>m;
for(int i=1;i<=n;i++)std::cin>>a[i];
int l=1,r=1e18;
while(l<r){
int mid=(l+r+1)>>1;
if(ck(mid)){
l=mid;
}else{
r=mid-1;
}
}
ans=0;
for(int i=1;i<=n;i++){
int cnt=(l/a[i]+1)/2;
ans+=cnt;
m-=cnt*cnt*(a[i]);
}
std::cout<<ans+m/(l+1)<<'\n';
}
signed main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout<<std::setiosflags(std::ios::fixed)<<std::setprecision(2);
int t = 1, i;
for (i = 0; i < t; i++){
solve();
}
return 0;
}