zoukankan      html  css  js  c++  java
  • 【NOIP2011提高组T5】聪明的质监员-二分答案+前缀和

    测试地址:聪明的质监员

    做法:可以发现,Y的值是随着W的递增而递减的,满足单调性,因此可以用二分答案把查找答案的复杂度降为O(log n)。设lf为左边界,rt为右边界,lf初始化为0,rt初始化为最大的w[i]+1(即矿石中一个都不满足w[i]≥W的情况),然后进行二分答案。设mid=(lf+rt)/2,对于每个mid,算出Y的值,如果Y<S,则表示左半区间内的数更靠近S,否则表示右半区间内的数更靠近S(想一想,为什么?),一次次地缩小查找范围,就可以找到最好的W了。

    那么现在我们只需解决求Y值的问题,由于区间有m个,如果求每个区间的Yi时都要O(n)的复杂度的话,那么整个求Y值的过程的复杂度就是O(nm),显然是不可能承受的。再分析Yi的特征,发现其由两部分组成:w[i]≥W的矿石数量和它们的价值之和。这两个部分都是一个求和的关系,又考虑到在W相同的情况下,这个区间内数的值是不会变化的,所以我们用两个数组sum1和sum2分别表示区间[1,i]内的w[i]≥W的矿石数量和它们的价值之和,那么如果我们要求一个区间[l,r]的Yi,则:

    Yi=(sum1[r]-sum1[l-1])*(sum2[r]-sum2[l-1])

    这样一来,求Yi的复杂度就降为O(1)了,而sum1和sum2只需计算一次,复杂度为O(n),因而整个求Y值的过程的时间复杂度就是O(n+m),在加上二分答案,整个程序的复杂度就是O((n+m)log n),问题完美解决。

    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    using namespace std;
    ll n,m,S,w[200010],v[200010],lf=0,rt=0,ans;
    ll sum1[200010]={0},sum2[200010]={0};
    int l[200010],r[200010];
    
    ll ab(ll a)
    {
      if (a<0) return -a;
      else return a;
    }
    
    bool calc(ll W)
    {
      sum1[0]=sum2[0]=0;
      for(int i=1;i<=n;i++)
      {
        sum1[i]=sum1[i-1];sum2[i]=sum2[i-1];
        if (w[i]>=W) sum1[i]++,sum2[i]+=v[i];
      }
      ll s=0;
      for(int i=1;i<=m;i++)
        s+=(sum1[r[i]]-sum1[l[i]-1])*(sum2[r[i]]-sum2[l[i]-1]);
      if (ab(s-S)<ans) ans=ab(s-S);
      return s<S;
    }
    
    int main()
    {
      scanf("%lld%lld%lld",&n,&m,&S);
      for(int i=1;i<=n;i++)
      {
        scanf("%lld%lld",&w[i],&v[i]);
    	rt=max(rt,w[i]);
      }
      rt++;
      for(int i=1;i<=m;i++)
        scanf("%d%d",&l[i],&r[i]);
      
      ans=1000000;
      ans=ans*ans;
      
      while(lf<=rt)
      {
        ll mid=(lf+rt)>>1;
    	if (calc(mid)) rt=mid-1;
    	else lf=mid+1;
      }
      
      printf("%lld",ans);
      
      return 0;
    }
    


  • 相关阅读:
    MATLAB中的fopen、fclose、fprintf、fscanf、fread、fwrite
    网站制作中常用的一些网页布局
    更快学习 JavaScript 的 6 个思维技巧---分享
    根据数据生成列表
    动态生成随机背景色表格
    根据数据生成表单
    _鼠标移动跟随效果
    tab菜单事件
    全选 反选案例
    onresize的应用--自适应弹窗
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793881.html
Copyright © 2011-2022 走看看