• 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;
    }
  • 相关阅读:
    try,except,finally的用法
    python实现蓝牙通信
    分布式全局ID的几种生成方案
    为什么要两次调用encodeURI来解决乱码问题
    jenkins配置到gitlab拉代码
    查看IOS-app证书到期时间
    使用SSH方式实现Git远程连接GitHub/gitlab
    Git 分支
    jenkins构建后操作archive the artfacts的用法
    MAC 安装jenkins
  • 原文地址:https://www.cnblogs.com/pigba/p/9040794.html
Copyright © 2020-2023  润新知