zoukankan      html  css  js  c++  java
  • CTSC[2018] 调和果汁

    这题在今年CTSC中属于非常可做的题吧...

    首先注意题中询问的美味度为最小值而不是求和,

    所以自然而然能想到二分美味度下界,

    然后对于美味度大于下届的这些果汁中随便选,凑出g[i],发现选谁都是等价的,所以直接选便宜的,相当于选前g[i]便宜的,与L[i]比较大小

    然后求前k小的和显然可以用主席树做,当然我的主席树可能比较垃圾....

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    typedef long long ll;
    const int N=1e5+5;
    ll n,m,maxn,tcnt,maxp;
    ll u,v;
    ll rt[20*N];
    struct tree
    {
      ll l,r;
      ll sum,cnt;
    }t[20*N];
    struct juice
    {
      ll d,p,l;
      inline void read()
      {
        scanf("%lld%lld%lld",&d,&p,&l);
        maxn=max(maxn,d);
        maxp=max(maxp,p);
      }
      friend inline bool operator < (const juice &a,const juice &b)
      {
        return a.d<b.d;
      }
    }a[N];
    
    void insert(ll y,ll &x,ll l,ll r,ll p,ll w)
    {
      t[x=++tcnt]=t[y];
      t[x].cnt+=w;
      t[x].sum+=w*p;
      ll mid=l+r>>1;
      if(l==r) return ;
      if(p<=mid) insert(t[y].l,t[x].l,l,mid,p,w);
      else insert(t[y].r,t[x].r,mid+1,r,p,w);
    }
    bool query(ll y,ll x,ll l,ll r,ll u,ll v)
    {
      ll delta1=t[t[x].l].cnt-t[t[y].l].cnt,delta2=t[t[x].l].sum-t[t[y].l].sum;
      //printf("%d %d %lld %lld
    ",l,r,delta1,delta2);
      if(l==r)
        {
          ll lft1=t[x].cnt-t[y].cnt,lft2=t[x].sum-t[y].sum;
          if(lft1<v) return 0;
          return u>=(lft2/lft1)*v;
        }
      ll mid=l+r>>1;
      if(delta1>=v)
        {
          if(u>=delta2) return 1;
          return query(t[y].l,t[x].l,l,mid,u,v);
        }
      else
        {
          if(u<delta2) return 0;
          return query(t[y].r,t[x].r,mid+1,r,u-delta2,v-delta1);
        }
      
    }
    bool check(ll x)
    {
      ll l=1,r=n;
      while(l<r)
        {
          ll mid=l+r>>1;
          if(a[mid].d>=x) r=mid;
          else l=mid+1;
        }
      //printf ("%d:%d-%lld-%lld
    ",x,l,u,v);
      return query(rt[l-1],rt[n],1,maxp,u,v);
    }
    ll solve()
    {
      ll l=1,r=maxn;
      if(!check(1)) return -1;
      
      while(l<r)
        {
          ll mid=l+r+1>>1;
          if(check(mid)) l=mid;
          else r=mid-1;
        }
      return l;
    }
    int main()
    {
      scanf("%lld%lld",&n,&m);
      for(ll i=1;i<=n;i++) a[i].read();
      sort(a+1,a+n+1);
      for(ll i=1;i<=n;i++) insert(rt[i-1],rt[i],1,maxp,a[i].p,a[i].l);
      ll x,y;
      for(ll i=1;i<=m;i++)
        {
          scanf("%lld%lld",&u,&v);
          printf("%lld
    ",solve());
        }
      return 0;
    }
  • 相关阅读:
    怎样在caffe中添加layer以及caffe中triplet loss layer的实现
    【java】为数组全部元素赋同样的值 以及 数组之间的复制
    POJ 2386 Lake Counting 搜索题解
    android中实现内容搜索
    JNI之——在cmd命令行下编译执行C/C++源文件
    怎样编写高效android代码
    http headers
    matlab 工具函数、matlab toolbox(工具箱)
    数列收敛与数列极限
    数列收敛与数列极限
  • 原文地址:https://www.cnblogs.com/pigba/p/9040794.html
Copyright © 2011-2022 走看看