leeing Sunlight (补)

这道题呢,就是一个高精实数二分,英文题有点难理解

题外话:(在这次比赛的时候深深的感受到了无助,之前不理想一直在感动自己,觉着就是自己不够努力,就一直努力学着(其实就是一个让自己努力的理由),结果努力到现在,还是不如别人,后来才慢慢接受差距感,真的让人不舒服)

Klee’s definition of playing is throwing explosives all over the place; she is particularly fond of “fish blasting” — throwing bombs in lakes full of fish. Today, Klee also plans to blast fish in Starfell Lake. There are n fish in Starfell Lake. Klee will use a bomb with power x, then, every fish whose HP less than or equal to x will be blasted. However, Klee doesn’t know HP of every fish. Instead, she only knows HP of the i-th fish is a uniformly random real number in [li , ri ]. Now, Klee wants to determine minimum possible x such that the expected number of blasted fish is greater or equal to m. Your answer will be considered correct, if its absolute or relative error does not exceed 10−4 . More formally, if your answer is a and jury’s answer is b, your answer will be considered correct if |a−b| max(1,b) ≤ 10−4 . Input The first line contains two integers n, m (1 ≤ m ≤ n ≤ 105 ) — the number of fish and Klee’s expection of the number of blasted fish. In the following n line, each line contains two real numbers li , ri (0 ≤ li ≤ ri ≤ 109 ), which means HP of the i-th fish will be a random real number in [li , ri ]. Output Output minimum possible x such that the expected number of blasted fish is greater or equal to m.

#include<bits/stdc++.h>
using namespace std;
const int N=2e6;
struct node
{
    double l,r;
}a[N];
double s[N];
int n,m;
double MIN=0x3f3f3f3f,MAX=0.0;
bool check(double x)//对于二分不管是实数二分还是整数二分check函数是最重要的当然边界处理也很重要
{
       double ans=0;
      for(int i=0;i<n;i++)
      {
         if(x>=a[i].r)ans+=1;
         else if(x>a[i].l)
         ans+=(x-a[i].l)/s[i];
         if(ans>=m)return true;
      }
      return false;
}
void solve()
{
      for(int i=0;i<n;i++)
      {
      cin>>a[i].l>>a[i].r;
      s[i]=a[i].r-a[i].l;
      MIN=min(a[i].l,MIN);
      MAX=max(a[i].r,MAX);
      }
      double l=MIN,r=MAX;//二分的范围先处理出来
      while(r-l>1e-5)
      {
       double mid=(l+r)/2;
        if(check(mid))r=mid;
        else l=mid;
      }
       printf("%.10lf",r);
}
int main()
{

    cin>>n>>m;
    solve();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值