codeforces 985 D. Sand Fortress(二分+思维)
2 seconds
256 megabytes
standard input
standard output
You are going to the beach with the idea to build the greatest sand castle ever in your head! The beach is not as three-dimensional as you could have imagined, it can be decribed as a line of spots to pile up sand pillars. Spots are numbered 1 through infinity from left to right.
Obviously, there is not enough sand on the beach, so you brought n packs of sand with you. Let height hi of the sand pillar on some spot i be the number of sand packs you spent on it. You can't split a sand pack to multiple pillars, all the sand from it should go to a single one. There is a fence of height equal to the height of pillar with H sand packs to the left of the first spot and you should prevent sand from going over it.
Finally you ended up with the following conditions to building the castle:
- h1 ≤ H: no sand from the leftmost spot should go over the fence;
- For any
|hi - hi + 1| ≤ 1: large difference in heights of two neighboring pillars can lead sand to fall down from the higher one to the lower, you really don't want this to happen;
: you want to spend all the sand you brought with you.
As you have infinite spots to build, it is always possible to come up with some valid castle structure. Though you want the castle to be as compact as possible.
Your task is to calculate the minimum number of spots you can occupy so that all the aforementioned conditions hold.
The only line contains two integer numbers n and H (1 ≤ n, H ≤ 1018) — the number of sand packs you have and the height of the fence, respectively.
Print the minimum number of spots you can occupy so the all the castle building conditions hold.
5 2
3
6 8
3
Here are the heights of some valid castles:
- n = 5, H = 2, [2, 2, 1, 0, ...], [2, 1, 1, 1, 0, ...], [1, 0, 1, 2, 1, 0, ...]
- n = 6, H = 8, [3, 2, 1, 0, ...], [2, 2, 1, 1, 0, ...], [0, 1, 0, 1, 2, 1, 1, 0...] (this one has 5spots occupied)
The first list for both cases is the optimal answer, 3 spots are occupied in them.
And here are some invalid ones:
- n = 5, H = 2, [3, 2, 0, ...], [2, 3, 0, ...], [1, 0, 2, 2, ...]
- n = 6, H = 8, [2, 2, 2, 0, ...], [6, 0, ...], [1, 4, 1, 0...], [2, 2, 1, 0, ...]
【题意】
对给定的nn,HH,把n划分为a1,a2,a3,...a1,a2,a3,...,要求首项a1≤Ha1≤H,相邻两项之差不大于1,而且最后一项必须是1。总个数要最少,输出这个最小的总个数。
【思路】
只求总个数,所以不必关心具体的序列。假设现在要分析总和为n,k个数的序列是否存在,就得去分解n,这件事是很难完成的,不如换一个角度,反向分析:所有满足“首项≤H≤H,相邻两项差不大于1,最后一项是1”的k个数的序列当中,有没有总和刚好是n的呢?
很容易发现 ,把kk定下来以后,一个满足条件的序列的总和,它的取值是一个连续的范围,而且下界明显是kk,那么上届是多少呢?
在kk个位置中填入最大的数,根据奇偶的不同,可能有下面两种情况,右边一定是黄色所示的三角形。如果n比较小可能只有黄色部分。
只要kk个数的和的区间[k,maxSUM][k,maxSUM]中包含nn,kk就是可行的。而且因为kk越大,maxSUM就越大,所以如果kk可行,那么k+1k+1也一定可行,正是因为这种单调性,可以kk进行二分查找。
【注意】
由于n, H比较i大,可能会出现乘积结果long long 溢出。为了避免在1~n进行二分,考虑一个更好的上届。我使用的下面的这种摆放的方法得到的上届:(k/2)2=n(k/2)2=n,所以最多用k=2√nk=2n个数
#include<stdio.h>
#include<math.h>
typedef long long ll;
ll n, H;
//绝对值
#define mabs(x) ((x)>0?(x):(0-(x)))//a, a+1, ...,b连续求和
#define SUM(a,b) (a+b)*(mabs(b-a)+1)/2
ll check(ll len)
{//检查三种情况,求maxSUM并于n比较
ll area;
if (len <= H)
area = SUM(, len);
else
{
area = SUM(, H-);
len -= H;
if (len & )
area = area + SUM(H, H + len / ) + SUM(H + len / , H);
else
area = area + SUM(H, H + len / ) + SUM(H + len / - , H);
}
return area >= n;
} //二分查找k
ll binsch(ll fr,ll to)
{
ll l = fr - , r = to + , m;
while (l+<r)
{
m = (l + r) / ;
if (check(m)!= )l = m;
else r = m;
}
return r;
} int main()
{
scanf("%I64d %I64d", &n,&H);
ll r = *sqrt(n)+;
ll ans=binsch(, r);
printf("%I64d", ans);
}
codeforces 985 D. Sand Fortress(二分+思维)的更多相关文章
- Codeforces 985 D - Sand Fortress
D - Sand Fortress 思路: 二分 有以下两种构造, 分别二分取个最小. 代码: #include<bits/stdc++.h> using namespace std; # ...
- codeforces 799 C. Fountains(二分+思维)
题目链接:http://codeforces.com/contest/799/problem/C 题意:要求造2座fountains,可以用钻石,也可以用硬币来造,但是能用的钻石有限,硬币也有限,问能 ...
- Educational Codeforces Round 44#985DSand Fortress+二分
传送门:送你去985D: 题意: 你有n袋沙包,在第一个沙包高度不超过H的条件下,满足相邻两个沙包高度差小于等于1的条件下(注意最小一定可以为0),求最少的沙包堆数: 思路: 画成图来说,有两种可能, ...
- Codeforces 985 最短水桶分配 沙堆构造 贪心单调对列
A B /* Huyyt */ #include <bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define mkp(a, ...
- codeforces 895B XK Segments 二分 思维
codeforces 895B XK Segments 题目大意: 寻找符合要求的\((i,j)\)对,有:\[a_i \le a_j \] 同时存在\(k\),且\(k\)能够被\(x\)整除,\( ...
- CodeForces 985D Sand Fortress
Description You are going to the beach with the idea to build the greatest sand castle ever in your ...
- codeforces E. Mahmoud and Ehab and the function(二分+思维)
题目链接:http://codeforces.com/contest/862/problem/E 题解:水题显然利用前缀和考虑一下然后就是二分b的和与-ans_a最近的数(ans_a表示a的前缀和(奇 ...
- codeforces 814 C. An impassioned circulation of affection(二分+思维)
题目链接:http://codeforces.com/contest/814/problem/C 题意:给出一串字符串然后q个询问,问替换掉将m个字符替换为字符c,能得到的最长的连续的字符c是多长 题 ...
- codeforces 808 E. Selling Souvenirs (dp+二分+思维)
题目链接:http://codeforces.com/contest/808/problem/E 题意:最多有100000个物品最大能放下300000的背包,每个物品都有权值和重量,为能够带的最大权值 ...
随机推荐
- 利用$http获取在服务器的json数据
以下是存储在web服务器上的 JSON 文件: http://www.runoob.com/try/angularjs/data/Customers_JSON.php { "records& ...
- 使用科大讯飞时碰上的问题(unity调用Android)
使用科大讯飞的时候公司已经有人配置好了Android项目,由于装机量的限制,所以基本上要更换里面的资源和更改app_id,然而在unity那边调用的时候总是出现各种各样的问题,特此记录下来 1.唤醒未 ...
- GO学习笔记:struct类型
Go语言中,也和C或者其他语言一样,我们可以声明新的类型,作为其它类型的属性或字段的容器.例如,我们可以创建一个自定义类型person代表一个人的实体.这个实体拥有属性:姓名和年龄.这样的类型我们称之 ...
- C++空类和string类
1. 空类 1.1 空类默认哪六个成员函数. class Empty { public: Empty(); //缺省构造函数 Empty e; Empty( const Empty& ); / ...
- IOS-日期处理
主要有以下类: NSDate -- 表示一个绝对的时间点NSTimeZone -- 时区信息NSLocale -- 本地化信息NSDateComponents -- 一个封装了具体年月日.时秒分.周. ...
- 24-THREE.JS 镜面高光材质
<!DOCTYPE html> <html> <head> <title>Example 04.07 - Mesh Phong material< ...
- vs中: 错误,未定义的标识符getline 的解决方法
这种情况一般都是,在使用的时候没有include<string>而导致的,加上就可以正确编译通过
- 【dlbook】数学基础
[代数] Moore-Penrose 伪逆 [概率信息论] 自信息,香农熵,衡量两个分布的差异:kl散度 \ 交叉熵 [数值] 溢出: softmax计算的时候要关注上溢和下溢,如果所有X都相等且为很 ...
- 【CSAPP】一、计算机系统漫游
一.位+上下文 文本文件 / 二进制文件: 文本文件是只由ASCII码构成的文件 二.从源代码到可执行文件的顺序 源代码 ——> 可执行文件(机器代码)共有四步: 全过程代码 gcc hello ...
- 你不知道的sticky
position:sticky,Chrome新版本已经做了支持.sticky的中文翻译是“粘性的”,position:sticky表现也符合这个粘性的表现.基本上,可以看出是position:rela ...