Problem:
Problem F: Abyss and Coins
数直線上の座標 $0,1,2,\ldots,N$ に足場があり、座標 $i$ の足場には $i$ 枚のコインがあります。
ウサギのネムは、最初座標
	$0$の足場にいて、好きな回数だけジャンプを繰り返すことによって、足場にあるコインを集めたいと思っています。
$1$ 回目のジャンプでは好きな距離だけ飛ぶことが出来ますが、 $2$ 回目以降は、今いる足場の座標と $1$ つ前にいた足場の座標の丁度真ん中の座標にしか飛ぶことが出来ません。
つまり、 $i$ 回ジャンプをした後到達する座標を $x_i$ とし、最初に飛ぶ座標を $X$ とすると、
$x_0=0$,
$x_1=X$,
$x_{i+2}=\frac{(x_{i+1}+x_i)}{2}$ ただし、 $i \geq 0$
となります。
飛んだ先に足場が存在する場合、その足場にあるコインを全て手に入れることが出来ます。
しかし、既に $1$ 回以上来た事のある足場を再度訪れても、もう一度コインを入手することは出来ません。
ジャンプによって飛んだ先に足場が存在しない場合、ネムは奈落の底に落ちてしまい、今まで集めたコインを全て失って帰ることになります。
逆に、いずれかの足場の上に立っている場合、ネムはいつでもジャンプを繰り返すことをやめ、その時点で持っているコインを全て持ち帰ることが出来ます(座標 $0$ に戻る必要はありません)。
ネムが持ち帰ることが出来るコインの枚数の最大値を求めてください。
Constraints
入力は以下の条件を満たす。
$ 1 \leq N \leq 10^{12}$
入力は整数である。
Input
入力は以下の形式で与えられる。
$N$
Output
ネムが持ち帰ることが出来るコインの枚数の最大値を出力してください。
また、末尾に改行を出力するのを忘れないようにしてください。
Sample Input 1
3
Sample Output 1
3
最初に飛ぶ距離として $2$ を選ぶと、 $1$ 回目のジャンプで座標 $2$ の足場に、 $2$ 回目のジャンプで座標 $1$ の足場に飛ぶことができます。
ここで帰ると、得られるコインは $2+1=3$ 枚となり、これが最大です。
もし $3$ 回目のジャンプを行うと、移動先の座標は $\frac{1+2}{2}=1.5$ となり、足場が存在しないため奈落の底に落ちてしまいます。
また、 $0→1→2→3$ や $0→2→3$ といった移動は許されていないことに注意してください。
なお、最初に飛ぶ距離として $4,-1,1.99999$ などを選ぶこともできますが、このようにした場合 $1$ 枚もコインを得ることなく奈落の底に落ちてしまいます。
Sample Input 2
15
Sample Output 2
27
$ 0 \to 12 \to 6 \to 9$ と飛んでから帰るのが最適です。
Sample Input 3
1000000000000
Sample Output 3
24586301676657
オーバーフローに注意してください。

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
 
const double pi = 3.141592653589793238462643383279;
using namespace std;

//typedef
//------------------------------------------
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
typedef pair<int, PII> TIII;
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<LL> VLL;
typedef vector<VLL> VVLL;
 
 
//container util
//------------------------------------------
#define ALL(a)  (a).begin(),(a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define MP make_pair
#define SQ(a) ((a)*(a))
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
 
 
//repetition
//------------------------------------------
#define FOR(i,s,n) for(int i=s;i<(int)n;++i)
#define REP(i,n) FOR(i,0,n)
#define MOD 1000000007
 
 
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
 
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
 
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)

const long double EPS = 1e-6, PI = acos((long double)-1);

//ここから編集

ll GCD(ll a, ll b){
  return (b == 0)?a:GCD(b, a%b);
}
ll LCM(ll a, ll b){
  return a/GCD(a, b)*b;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(4);

  ll N;
  cin >> N;
  if(N == 1){
    cout << 1 << endl;
    return 0;
  }
  ll ans = 0;
  ll tmp = 1;
  while(tmp<=N){

    for(ll i=2; i<=100000; i++){
    ll prev = 0;
    ll pos = tmp*i;
    if(pos > N) break;
    if(pos<0) break;

    ll sum = 0;
    while(1){
      sum += pos;
      if((prev+pos)%2 != 0) break;

      

      ll tmp2 = pos;
      pos = (prev+pos)/2;

      prev = tmp2;      
    }
    ans = max(ans, sum);
    }
    tmp *= 2;
  }

  
  
  cout << ans << endl;
}
accuracy: 1
time_ms: 30
memory_kb: 3224
final_rank: 1

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <utility>
#include <string>
#include <queue>
#include <stack>

using namespace std;

typedef long long int ll;
typedef pair<int, int> Pii;

const ll mod = 1000000007;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll n;
  cin >> n;

  if (n == 1) {
    cout << 1 << endl;
    return 0;
  }

  vector<bool> sieve(10000001, true);
  sieve[0] = false;
  sieve[1] = false;
  for (ll p = 2; p <= 10000000; p++) {
    if (sieve[p]) {
      for (ll i = p * p; i <= 10000000; i += p) sieve[i] = false;
    }
  }

  ll ans = 0;
  for (int i = 0; i <= min(n, 10000000LL); i++) {
    if (!sieve[i]) continue;
    ll p = i;
    ll s = i;
    while (p + s <= n) {
      p += s;
      s <<= 1;
    }
    while (true) {
      ll score = p;
      ll prev = 0;
      ll now = p;
      while (!((prev + now) & 1)) {
        ll next = (prev + now) >> 1;
        score += next;
        prev = now;
        now = next;
      }
      ans = max(ans, score);
      if (s & 1) break;
      s >>= 1;
      p += s;
      if (p > n) break;
    }
  }

  cout << ans << endl;

  return 0;
}
accuracy: 0.5135135135135135
time_ms: 60
memory_kb: 4140
final_rank: 2

code_snippet: #include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <utility>
#include <string>
#include <queue>
#include <stack>

using namespace std;

typedef long long int ll;
typedef pair<int, int> Pii;

const ll mod = 1000000007;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll n;
  cin >> n;

  vector<bool> sieve(10000001, true);
  sieve[0] = false;
  sieve[1] = false;
  for (ll p = 2; p <= 10000000; p++) {
    if (sieve[p]) {
      for (ll i = p * p; i <= 10000000; i += p) sieve[i] = false;
    }
  }

  ll ans = 0;
  for (int i = 0; i <= min(n, 10000000LL); i++) {
    if (!sieve[i]) continue;
    ll p = i;
    ll s = i;
    while (p + s <= n) {
      p += s;
      s <<= 1;
    }
    while (true) {
      ll score = p;
      ll prev = 0;
      ll now = p;
      while (!((prev + now) & 1)) {
        ll next = (prev + now) >> 1;
        score += next;
        prev = now;
        now = next;
      }
      ans = max(ans, score);
      if (s & 1) break;
      s >>= 1;
      p += s;
      if (p > n) break;
    }
  }

  cout << ans << endl;

  return 0;
}
accuracy: 0.43243243243243246
time_ms: 60
memory_kb: 4148
final_rank: 3

code_snippet: // wa
#include <bits/stdc++.h>
using namespace std;

long long n;

long long calc(long long x);

int main() {
  cin >> n;
  long long res = 0, now = 1;
  while ((now << 1) <= n) now <<= 1;
  // 5にすると通る(証明可能？)
  for (int i = 0; i < 4; ++i) {
    if (now & 1) break;
    res = max(res, calc(n / now * now));
    now >>= 1;
  }
  for (int i = 0; i <= 100000000; ++i) {
    if (n - i <= 0) break;
    res = max(res, calc(n - i));
  }
  cout << res << endl;
  return 0;
}

long long calc(long long x) {
  long long flg = 1, sum = 0, now = 0;
  while (x) {
    now += x * flg;
    sum += now;
    if (x & 1) break;
    flg *= -1;
    x >>= 1;
  }
  return sum;
}
accuracy: 0.08108108108108109
time_ms: 200
memory_kb: 3032
final_rank: 4