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. c++11的新特性

    好奇心来源于下面的一段代码, 一个是unordered_map, 这是c++11新加的container. 另外还有unordered_set, unordered_multimap, unorder ...

  2. 使用哈工大LTP进行文本命名实体识别并保存到txt

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/broccoli2/article/det ...

  3. 2018-8-10-三种方式设置特定设备UWP-XAML-view

    title author date CreateTime categories 三种方式设置特定设备UWP XAML view lindexi 2018-08-10 19:16:52 +0800 20 ...

  4. 2019-4-29-dotnet-通过-WMI-获取系统安装软件

    title author date CreateTime categories dotnet 通过 WMI 获取系统安装软件 lindexi 2019-04-29 12:18:59 +0800 201 ...

  5. oracle交互命令

    (1)说明:可以替代变量,而该变量在执行时,需要用户输入. sql>select * from emp where job=’&job’; (2)edit  说明:该命令可以编辑指定的s ...

  6. importError: DLL load failed when import matplotlib.pyplot as plt

    importError: DLL load failed when import matplotlib.pyplot as plt 出现这种情况的原因, 大多是matplotlib的版本与python ...

  7. HZOJ 巨神兵

    60pts: 每个DAG的拓扑序是唯一的,所以考虑将DAG分层.f[i][j]记录当前选择的节点状态是i,最后一层的节点状态为j(dep取最大). 初始状态:$f[i][i]=1;i\in [1,1& ...

  8. @atcoder - AGC034E@ Complete Compress

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个 N 个点的树,编号为 1, 2, ..., N.第 i ...

  9. 解决移动端1px边框问题的几种方法

    1.边框粗细原因 在移动端下设置border为1px,在某些设备上看比1px粗. 这些由于不同的手机有不同的像素密度.在window对象中有一个devicePixelRatio属性,他可以反应css中 ...

  10. uva 10253 Series-Parallel Networks (整数划分+多重集)

    UVa Online Judge 题意是计算给定数量的边通过串联并联两种方式,能组成多少种不同的网络.将它转化为一个树形结构,也就是求有多少不同构的树. 代码如下: #include <cstd ...