ZR1158

http://www.zhengruioi.com/contest/446/problem/1158

给定限制的问题大多数都是容斥或者二分,或者二分之后容斥

首先,这个问题的第一步我们还是比较容易地去转换的,发现每个物品选的次数一定是\(2^i - 1\)次,而下一次我们就是花费\(2^i\)的代价去把答案\(+1\)

第\(x\)物品第\(i\)次选择的代价就是\(x\times 2^{i - 1}\),

现在问题变成了一个最大的代价\(cost\)使得所有代价小于等于\(cost\)的物品全部选择之后代价和不超过\(n\)

这个东西就有二分性,所以,不能直接二分答案的题目尝试把问题转化后进行二分,所以,我们接下来问题变成了对于一个给定的代价\(M\),求所有代价小于等于\(M\)的物品的代价之和

之后我们发现所有小于等于\(M\)的代价是长成这个样子的

\[\begin{align}
& 1\times 2 ^0 \ \ \ \ \ 2\times2^0 \ \ \ \ \ \dots \ \ \ \ \ M \times 2^0\\\
& 2\times2^1 \ \ \ \ \ 2\times2^1 \ \ \ \ \ \dots \ \ \ \ \ \lfloor\frac{M}{2}\rfloor\times2^1\\
& \dots
\end{align}
\]

很明显,最多只会有log行,每一行都是一个等差数列

而很明显尾项不能超过\(M\),所以项数就会变成\(\lfloor\frac{M}{x}\rfloor\)

这样我们直接暴力枚举log行,每一行都用等差数列求和算一下总的贡献即可

之后注意

我们设最终二分答案出的答案为\(x\),那么\(x\)一定是\(k\times2^i - 1\)的形式

可能会出现\(k+1\)不能全部放下,但是可以放一部分的情况,这一部分我们可以通过除法最后计算贡献

#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cctype>
#include<vector>
#include<ctime>
#include<cmath>
#include<set>
#include<map>
#define LL long long
#define pii pair<LL,LL>
#define mk make_pair
#define fi first
#define se second
using namespace std;
int T;LL n;
LL sum;
inline LL check(LL x){
sum = 0;
for(LL p = 1;p <= x;p <<= 1) sum += (x / p * p + p) * (x / p) / 2;
return sum;
}
inline LL geta(LL x){
LL res = 0;
for(LL p = 1;p <= x;p <<= 1) res += x / p;
return res;
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%lld",&n);int ans = 0;LL res = 0;
int l = 1,r = 2000000000;
while(l <= r){
int mid = (l + r) >> 1;
LL now = check(mid);
// printf("%d %d %d %lld\n",l,r,mid,now);
if(now <= n) l = mid + 1,ans = mid,res = now;
else r = mid - 1;
}
printf("%lld\n",geta(ans) + (n - res) / (ans + 1));
}
return 0;
}

ZR1158的更多相关文章

随机推荐

  1. 【JZOJ4894】【NOIP2016提高A组集训第16场11.15】SJR的直线

    题目描述 数据范围 解法 考虑逐次加入每一条直线. 对于当前已加入的直线集合L,现在要新加入一条直线l. 那么它产生的贡献,与平行线有关. 对于任意三条直线,如果其中任意两条平行,那么将不做贡献. 所 ...

  2. IDEA:将WEB-INF\lib下的Jar包添加到项目中

    打开Project Structure[可以使用快捷键:Ctrl+Alt+Shift+S] 左侧选中Modules,在Dependecies中,点击右侧"+"号,选择JARS or ...

  3. js中的replace问题和textarea回车符问题

    在textarea中输入回车符 在js读取textarea中的值有\r\n然后到业务层转换到string中就有可能变成空格形式然后被存入数据库,当在取出此值的时候则会变成空格的形式,因此我们需要将不显 ...

  4. 阿里云容器Kubernetes监控(九) - Kubernetes事件离线工具kube-eventer正式开源

    前言 监控是保障系统稳定性的重要组成部分,在Kubernetes开源生态中,资源类的监控工具与组件百花齐放.除了社区自己孵化的metrics-server,还有从CNCF毕业的Prometheus等等 ...

  5. MySQL主备模式的数据一致性解决方案

     根据阿里交易型业务的特点,以及在双十一这样业内罕有的需求推动下,我们在官方的MySQL基础上增加了非常多实用的功能.性能补丁.而在使用MySQL的过程中,数据一致性是绕不开的话题之一.本文主要从阿里 ...

  6. php switch判断一个数所在的范围

    <?php header("content-type:text/html;charset=utf8"); $score=70; switch($score) { case $ ...

  7. 通过反射拿到构造方法 Day25

    package com.sxt.constructor; /* * 反射 * Class类拿到构造方法 */ import java.lang.reflect.Constructor; public ...

  8. HZOJ 斐波那契(fibonacci)

    先说一个规律: 如图将每个月出生的兔子的编号写出来,可以发现一只兔子在哪一列他的父亲就是谁. 每列的首项可以通过菲波那契求得. 然后你就可以像我一样通过这个规律打表每个点的父亲,预处理出倍增数组,倍增 ...

  9. python unittest 框架添加测试用例及运行

    找出要测试的testcase,并加入到Testsuite,运行Testsuite并把结果给TestResult1.创建TestSuite实例对象suite = unittest.TestSuite() ...

  10. EC Round 41 (Rated for Div. 2)主席树 E. Tufurama

    简单分析一下,对于x<y,求a[x]>=y 同时a[y]>=x 再简化一下,求1-a[y]区间内大于>=y的个数...主席树牛逼 #include<iostream> ...