1 条题解

  • 0
    @ 2023-11-17 22:43:03

    二分练习题解

    for(int i=1;i<=n;i++){
    		if(b[i]<=x){
    			y+=(x-b[i])/k[i]+1;
    		}
    	}
    

    首先第一句话:“第ii个序列可以表示成ki×x+bik_i×x+b_i 的形式x=0,1,2...(x=0,1,2...)” 我们得知公式是k[i]×x+b[i]k[i]×x+b[i],那么我们又得知这个公式后的结果要小于等于MM才是有效范围,所以就有了22种情况,分别是小于等于和大于,那么大于就是一个都没有的情况,序列中最小的数都比这个数大所以就是一个都没有嘛。

    那么否则里面有多少个我们对上面的公式做个移项 k[i]×xMb[i]k_{[i]}×x \le M-b_{[i]}

    这时候我们再把k[i]k{[i]}移过去: xMb[i]k[i]x \le \frac{M-b_[i]}{k_[i]}

    那么具体有多少个那就是0,1,20,1,2一直到Mb[i]÷k[i]M-b_[i]÷k[i]这里是整除k[i]k[i],所以具体多少个数我们还需要取下整。 因此最终公式是xMb[i]k[i]x \le \lfloor \frac{M-b_[i]}{k_[i]} \rfloor,转化成程序就是(xb[i])/k[i]+1(x-b[i])/k[i]+1

    每一个数列小于等于MM的数有多少个后,那么一共的话就是把每一组数列中\le等于的个数加起来就知道分界线位置是在左边还是右边了。

    那么在梳理下这是怎么二分数的呢? 我们是要这么想,现在要去看看这一个合并完以后的这一个序列里面,小于11的,小于等11的数有多少个,小于等于22的数有多少个,等等等等一直去看小于等于这里面的数有多少个,那么我们小于等于ii的数有多少个,随着ii变大,那这样数字个数也会变多,那最后一定能找到一条分界线,对于分界线左边的xx小于等于xx的数字有小于MM个,对于分界线右边的些xx小于等于xx的数字有大于等于MM个,那比如说分界线最后在LLRR之间,那最后MM小的一定是RR,那现在我们就是要把分界线,我们去把它二分出来,那分界线怎么二分呢?就是我们二分的时候是吧,我要去看当前小于等于MM的数字有多少个,那我们就每一个序列,我们每个序列去看过来,看每个序列小于等于MM有多少个,我把它加起来我就知道了,总共小于等于MM的有多少个了,对吧?那么这个题的话就是这样的,那么你看一看小于等MM数字有多少个就可以求出来了。

    信息

    ID
    1918
    时间
    1000ms
    内存
    256MiB
    难度
    8
    标签
    递交数
    26
    已通过
    5
    上传者