D2. Café y trabajo de curso (versión difícil) (Pensamiento + Codicia)

https://codeforces.com/problemset/problem/1118/D2


Ideas:

A primera vista, puede ver que la respuesta se puede dividir en dos. Entonces esta pregunta es diferente de la suma del prefijo, aunque la resta es fija cada vez, el prefijo suma primero para restar un número negativo, y la respuesta es +0;

Considere el cheque codicioso después de la dicotomía.

Hay x días, y el mayor sin pérdidas se puede agregar todos los días, para un total de x. Luego hay una pérdida después de beber. Y así. Después de clasificar, cada grupo recibe la contribución.

#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar();	while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL a[maxn];
bool cmp(LL A,LL B){return A>B;}
bool check(LL x,LL n,LL m){
     LL sum=0;
     LL cnt=0;
     for(LL i=1;i<=n;i++){
        cnt++;
        LL div=(cnt-1)/x;
        sum+=max((LL)0,(a[i]-div));
     }
     if(sum>=m) return true;
     else return false;
}
int main(void)
{
  cin.tie(0);std::ios::sync_with_stdio(false);
  LL n,m;cin>>n>>m;
  for(LL i=1;i<=n;i++) cin>>a[i];
  sort(a+1,a+1+n,cmp);
  LL l=1;LL r=n+1;
  while(l<r){
     LL mid=(l+r)>>1;
     if(check(mid,n,m)) r=mid;
     else l=mid+1;
  }
  if(l==n+1){
    cout<<"-1"<<"\n";
  }
  else cout<<l<<"\n";
return 0;
}

 

Supongo que te gusta

Origin blog.csdn.net/zstuyyyyccccbbbb/article/details/115264997
Recomendado
Clasificación