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. Directx11教程(32) 纹理映射(2)

    原文:Directx11教程(32) 纹理映射(2)     在写代码之前,我们先制作一个dds文件.从网上找到了一张照片,处理成为512*512,保存为jpg格式.     启动微软的directx ...

  2. Leetcode824.Goat Latin山羊拉丁文

    给定一个由空格分割单词的句子 S.每个单词只包含大写或小写字母. 我们要将句子转换为 "Goat Latin"(一种类似于 猪拉丁文 - Pig Latin 的虚构语言). 山羊拉 ...

  3. bzoj1060 时态同步

    Description 小Q在电子工艺实习课上学习焊接电路板.一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数字1,2,3….进行标号.电路板的各个节点由若干不相交的导线相连接,且对于电路板 ...

  4. jenkins使用教程!

    http://jenkins-ci.org/ 首先去官方下载war包,直接安装jenkins的方式比较麻烦. 下载tomcat,jdk和ant cd /optwget http://mirrors.h ...

  5. C++2:函数与传递

    C++2:函数与传递 赵强 201831061427 目录   一.函数   二.函数重载   三.值传递   四.地址传递   五.递归函数 一.函数   我们在代码编译中常常会用到函数,函数是模块 ...

  6. 2019-10-23-WPF-使用-SharpDx-渲染博客导航

    title author date CreateTime categories WPF 使用 SharpDx 渲染博客导航 lindexi 2019-10-23 21:10:13 +0800 2019 ...

  7. POJ-3159_Candies

    Candies Time Limit: 1500MS Memory Limit: 131072K Description During the kindergarten days, flymouse ...

  8. Python基础:12函数细节

    一:返回值 当没有显式地返回元素时,Python 会返回一个None.如果函数返回多个对象,python 把他们聚集起来并以一个元组返回. 二:创建函数 1:强烈推荐,在函数体之前,编写函数的文档字符 ...

  9. 11-2 css盒模型和浮动以及矢量图用法

    一 盒模型 1属性 width:内容的宽度 height: 内容的高度 padding:内边距,边框到内容的距离 border: 边框,就是指的盒子的宽度 margin:外边距,盒子边框到附近最近盒子 ...

  10. python---异常处理与反射

    一.异常处理 1.异常基础 在编程过程中为了增加友好性,在程序出现bug时一般不会将错误信息显示给用户,而是现实一个提示的页面,通俗来说就是不让用户看见大黄页!!! try: pass except ...