首页 > 其他分享 >CF609D题解

CF609D题解

时间:2024-02-13 12:22:19浏览次数:39  
标签:ch log int 题解 CF609D mid 排序

Gadgets for dollars and pounds

题目传送门

题解

给一个单 \(\log\) 题解。

“求最早完成买 \(k\) 样东西的天数。”——很明显的二分答案。

在检验函数中,我们应当把前 \(k\) 小的物品费用之和与总金额作比较,其它题解大多使用直接排序的方法,于是就多了一只 \(\log\)。其实没有必要,因为总共只有两种物品,我们使用类似归并排序的双指针法,这样只需要在二分的外层 \(O(n\log n)\) 排序,二分内层 \(O(n)\) 归并,总复杂度 \(O(n\log n)\)。

但是这题居然要输出方案,需要记录排序前的位置,实在多少有点恶心。

代码:

/*
 * @Author: operator_ 
 * @Date: 2024-02-13 11:40:49 
 * @Last Modified by: operator_
 * @Last Modified time: 2024-02-13 12:12:14
 */
#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int rd() {
    int s=0,m=0;char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-')m=1;ch=getchar();}
    while( isdigit(ch)) s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
    return m?-s:s;
}
int n,m,k,s,v[3][200005],p[3][200005],l[3];
struct QWQ{int v,id;} a[3][200005];
bool cmp(QWQ a1,QWQ a2) {return a1.v<a2.v;}
bool check(int mid) {
    int i=0,j=0,sum=0;
    while(i+j<k)
        if(a[1][i+1].v*v[1][mid]<a[2][j+1].v*v[2][mid])
            sum+=a[1][++i].v*v[1][mid];
        else sum+=a[2][++j].v*v[2][mid];
    return sum<=s;
}
signed main(){
    cin>>n>>m>>k>>s;
    v[1][0]=v[2][0]=INT_MAX;
    for(int i=1;i<=n;i++) {
        v[1][i]=rd();
        if(v[1][i-1]>v[1][i]) p[1][i]=i;
        else p[1][i]=p[1][i-1],v[1][i]=v[1][i-1];
    }
    for(int i=1;i<=n;i++) {
        v[2][i]=rd();
        if(v[2][i-1]>v[2][i]) p[2][i]=i;
        else p[2][i]=p[2][i-1],v[2][i]=v[2][i-1];
    }
    p[1][n+1]=p[2][n+1]=n+1;
    for(int i=1,t,d;i<=m;i++)
        t=rd(),d=rd(),a[t][++l[t]]={d,i};
    a[1][++l[1]].v=a[2][++l[2]].v=INT_MAX;
    sort(a[1]+1,a[1]+l[1]+1,cmp);sort(a[2]+1,a[2]+l[2]+1,cmp);
    int ll=1,rr=n+1,ans=0;
    while(ll<=rr) {
        int mid=(ll+rr)>>1;
        if(!check(mid)) ll=mid+1;
        else ans=mid,rr=mid-1;
    }
    if(ans==n+1) return puts("-1"),0;
    cout<<ans<<endl;
    int i=0,j=0;
    while(i+j<k)
        if(a[1][i+1].v*v[1][ans]<a[2][j+1].v*v[2][ans])
            printf("%lld %lld\n",a[1][++i].id,p[1][ans]);
        else printf("%lld %lld\n",a[2][++j].id,p[2][ans]);
    return 0;
}

标签:ch,log,int,题解,CF609D,mid,排序
From: https://www.cnblogs.com/operator-/p/18014480

相关文章

  • P4559 [JSOI2018] 列队 题解
    题目链接:列队半年前mark的题,结果现在一下子就会做了。顺便写写我的手玩过程和复杂度说明。考虑比较特殊的情况:比较特殊的,发现从黑色到红色区间我们无论咋选择,由于\(\left|a_{right}-a_{left}\right|\),这玩意如果\(right\)表示红色的一边,那么这个绝对值可以直接拆掉,那么......
  • [ARC171E] Rookhopper's Tour 题解
    题目链接首先把\(m=2\)和\(m\)为奇数的情况判掉,由于我们要对合法的摆放方案计数,而一个摆放方案要判断合法性就必须通过一组合法的移动过程,对移动的状态进行记录以此转移和优化显然没啥前途,因此我们考虑摆放方案和移动过程之间的联系。一个比较显然的观察是摆放方案和移动过......
  • 2024牛客寒假算法基础集训营2个人补题题解(K、D)
    比赛链接:2024牛客寒假算法基础集训营2K、TokitsukazeandPassword(easy)题面看着很难实际上只要暴力的东西,赛时看了眼题面就溜了血亏爆搜,枚举\(abcd\)和_可能的值,枚举的情况只有\(9*8*7*6*9=27216\)种。判断按照枚举出的对应值排列出的密码是否满足条件,满足就\(ans++\)写完......
  • Atcoder Educational DP Contest 题解
    比赛链接:Atcoderr或者题单A:Frog1常规线性dp,注意到对于每个落点来说,青蛙只能由第\(i-1\)个石头或者第\(i-2\)个石头转移得到,那么我们让\(dp[i]\)为当跳到第\(i\)个石头上的最小费用。此时显然有:\[dp_i=\min(dp_{i-1}+\left|h_i-h_{i-1}\right|,dp_{i-2}+\left|h_......
  • JOISC 2018 题解
    JOISC2018loj上有几乎全部的题目,写了题意的就是loj上没有的。D1T1简单题。根据颜色段均摊的结论,每个点到根的路径上颜色段的总和是\(O(n\logn)\)的,于是直接每次暴力找颜色段即可。复杂度\(O(n\log^2n)\)。提交记录D1T2又是计算几何。我们需要画出一条闭合折线,并且......
  • JOISC 2017 题解
    JOISC2017loj上有几乎全部的题目,写了题意的就是loj上没有的。D1T1开场放大。首先,对于一个点,它最后覆盖的一定是一个矩形,这就意味着如果我们知道了\(u,d,l,r\)操作各用了多少次,他们之间的顺序是不重要的,我们可以直接当做把一种操作做完再做剩下的操作,这样就可以做到\(O(......
  • JOISC 2016 题解
    JOISC2016loj上有几乎全部的题目,写了题意的就是loj上没有的。D1T1一开始把题目看错了,还写了棵线段树。把询问离线,倒着扫一遍,就变成了求最长不上升子序列,用树状数组维护即可。提交记录D1T2来自Kubic的神仙做法。考虑Filp一个位置和剩下所有位置,记录每个数作为答案......
  • JOISC 2015 题解
    JOISC2015loj上有几乎全部的题目,写了题意的就是loj上没有的。D1T1简单题。因为\(k\)很小,考虑依次确定最后第\(i\)位是什么。我们倒序考虑所有操作,维护最后第\(i\)位当前在第几位,就可以一直推下去。提交记录D1T2直接暴力复杂度就是\(O(k4^k)\)的,可以通过。提交......
  • JOISC 2014 题解
    JOISC2014loj上有几乎全部的题目,写了题意的就是loj上没有的。D1T1想到了最短路的做法,不过可能还需要整体二分,复杂度至少有2log。有复杂度更优秀的贪心做法。把边按时间倒序加边,然后从终点开始dfs来更新每个点可以的最晚出发时间,每条边走之后肯定就不会再让答案变优了,......
  • CF1628E Groceries in Meteor Town 题解
    题目链接点击打开链接题目解法感觉就是很多个套路组合出来,但我有些套路都不会/ll套路1看到从一点出发,到其他点的路径上的最大权,可以想到\(kruskal\)生成树(这提示我不仅是图可以用\(kruskal\)生成树,树也可以捏)我们建大根的\(kruskal\)生成树,那么将问题转化成了找一个......