求最小值
int l=0,r=n+1,ans=0;
while(l<r) {
int mid=(l+r)>>1;
if(check(mid)) {
r=mid;
ans=mid;
}
else l=mid+1;
}
求最大值
int l=0,r=n+1,ans=0;
while(l<r) {
int mid=(l+r)>>1;
if(check(mid)) {
l=mid+1;
ans=mid;
}
else r=mid;
}
Bakkar is now a senior college student studying computer science. And as many students; Bakkar fell in love with one of his finest colleagues Maymona. And as Bakkar has no brothers he is counting on getting an exemption from the military service after graduation. He got engaged to Maymona in their senior year counting on the exemption and a job he will get after graduation at the same place where he was interning last summer.
Well, man does not always get what he wants; the neither planned nor expected happened. Bakkar’s mother is pregnant and will give birth to Hareedy before Bakkar can get his exemption.
Hareedy is now born and unfortunately Bakkar will have to postpone his job and marriage plans for a year as he will serve as a military soldier for one year.
On the first 45 days, soldiers are trained in the military training center. They have to do a variety of exercises daily. One day Bakkar woke up late and didn’t appear in the morning lineup at time. His commander is now angry and is going to punish him.
Bakkar is required to perform push-ups (the push-up position is called 6 esta’ed). His commander tells him to do them in reps (consecutive times) and then rest in between them. The commander wants him to follow a strict pattern. Given an upper limit, he will perform reps with increasing number of push-ups (1, 2, 3, …) to warm up, until he reaches the upper limit. After that, he starts decreasing the number of push-ups per rep until he stops completely (…, 3, 2, 1). After resting, he will repeat the process again but with a higher upper limit. The upper limit starts with 1, and increases each time by a value of 1.
Here are the first 16 reps:
1
1 2 1
1 2 3 2 1
1 2 3 4 3 2 1 …
The total number of push-ups he does is the sum of all the reps has has done so far. So for example, the total number of push-ups after completing 4 reps = 1+1+2+1 = 5, and after completing 7 reps = 1+1+2+1+1+2+3 = 11.
Bakkar now has to do at least N push-ups. This is very exhausting so he needs to know the minimum number of reps to complete using this pattern to reach his punishment reps.
Input
Your program will be tested on one or more test cases. The first line of the input will be a single integer T, the number of test cases (1 ≤ T ≤ 100,000). Followed by T test cases, each test case will be a single integer N, the number of push-ups Bakkar wants to perform (1 ≤ N ≤ 1018).
Output
For each test case print a single line containing “Case n:” (without the quotes) where n is the test case number (starting from 1) followed by a single space, then a single integer representing the minimum number of reps needed as described above.
Examples
Input
5
6
9
11
21
35
Output
Case 1: 5
Case 2: 7
Case 3: 7
Case 4: 13
Case 5: 19
这个形状第n层的总数是n平方,那么我们可以第一次二分去确定答案应该在哪一层,这里要用到平方和公式【n*(n+1)(2n+1)/6】,由平方和公式也可以确定第一次二分的上界为1e6左右,为了保险,开成2e6,。确定在哪一层之后就可以用第二次二分去确定答案在哪个位置。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;
const int maxn = 305;
ll b1(ll n)//确定层的位置,用求满足条件的最大值
{
ll l = 1,r = 2e6,ans = 0;
while(l < r)
{
ll mid = (l + r) / 2;
ll sum = mid * (mid+1) * (2*mid+1) / 6;
if(sum <= n)
{
l = mid + 1;
ans = mid;
}
else
r = mid;
}
return ans;
}
ll b2(ll k,ll i)//确定最后答案的位置,用求满足条件的最小值
{
ll l = 0,r = 2*i,ans = 0;
while(l < r)
{
ll mid = (l + r) / 2;
if(mid <= i)//注意分此时mid是在单调增的那边还是两边都有
{
if(mid*(mid+1)/2 >= k)
{
r = mid;
ans = mid;
}
else
l = mid + 1;
}
else
{
if(i*i - (2*i-1-mid)*(2*i-mid)/2 >= k)
{
r = mid;
ans = mid;
}
else
l = mid + 1;
}
}
return ans;
}
int main()
{
freopen("army.in","r",stdin);
int T;
scanf("%d",&T);
for(int t=1; t<=T; t++)
{
ll n;
scanf("%lld",&n);
ll i = b1(n);
ll ans = i*i;//前i层一共有i*i个数
ll k = n - i * (i+1) * (2*i+1) / 6;
i++;
ans += b2(k,i);
printf("Case %d: %lld\n",t,ans);
}
}