結果

問題 No.737 PopCount
ユーザー tonegawatonegawa
提出日時 2020-08-16 23:01:58
言語 C++17
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 3 ms / 1,000 ms
コード長 2,763 bytes
コンパイル時間 1,403 ms
コンパイル使用メモリ 123,992 KB
実行使用メモリ 5,376 KB
最終ジャッジ日時 2024-04-19 18:34:51
合計ジャッジ時間 2,152 ms
ジャッジサーバーID
(参考情報)
judge4 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
5,248 KB
testcase_01 AC 2 ms
5,376 KB
testcase_02 AC 2 ms
5,376 KB
testcase_03 AC 2 ms
5,376 KB
testcase_04 AC 2 ms
5,376 KB
testcase_05 AC 3 ms
5,376 KB
testcase_06 AC 2 ms
5,376 KB
testcase_07 AC 3 ms
5,376 KB
testcase_08 AC 2 ms
5,376 KB
testcase_09 AC 2 ms
5,376 KB
testcase_10 AC 2 ms
5,376 KB
testcase_11 AC 2 ms
5,376 KB
testcase_12 AC 3 ms
5,376 KB
testcase_13 AC 3 ms
5,376 KB
testcase_14 AC 2 ms
5,376 KB
testcase_15 AC 2 ms
5,376 KB
testcase_16 AC 2 ms
5,376 KB
testcase_17 AC 3 ms
5,376 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d>>(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define rep(a,b,c) for(ll a=b;a<c;a++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

void get(vll &a){re(i,a.size()) scanf("%lld",&a[i]);}
void get(vvl &a){re(i,a.size()) re(j,a[0].size()) scanf("%lld",&a[i][j]);}
void print(vll &a){re(i,a.size()) cout<<a[i]<<(i==a.size()-1?"\n":" ");}
void print(vvl &a){re(i,a.size()) re(j,a[0].size())cout<<a[i][j]<<(j==a[0].size()-1?"\n":" ");}

#define P 1000000007
vll t(61, 1);
ll n;

vvvl dp = VVV(61, 61, 2, -1);
ll f(ll keta, ll tgt, bool g){
  if(keta==-1) return 1;
  if(dp[keta][tgt][g]!=-1) return dp[keta][tgt][g];
  ll ret = 0;
  //1/0
  if(g){
    //0 or 1
    if(tgt==keta) ret =  f(keta-1, tgt, g);
    else ret = (2*f(keta-1, tgt, g))%P;
  }else{
    if(tgt==keta){
      if((n>>keta)&1) ret = f(keta-1, tgt, g);
      else ret = 0;
    }else{
      if((n>>keta)&1){
        ret = (f(keta-1, tgt, 1) + f(keta-1, tgt, 0))%P;
      }else{
        ret =  f(keta-1, tgt, 0); //0
      }
    }
  }
  return dp[keta][tgt][g] = ret;
}


vvvl dp2 = VVV(61, 61, 2, -1);
ll ff(ll keta, ll tgt, bool g){
  if(keta==-1) return 0;
  if(dp2[keta][tgt][g]!=-1) return dp2[keta][tgt][g];

  ll ret = 0;
  //1/0
  ll t2 = t[keta]%P;
  ll y = f(keta-1, tgt, 0)%P;
  ll z = f(keta-1, tgt, 1)%P;

  if(g){
    //0 or 1
    if(tgt==keta) ret =  (ff(keta-1, tgt, 1) + ((z*t2)%P))%P;//1
    else ret = (2*ff(keta-1, tgt, 1)+((z*t2)%P))%P;//0 or 1
  }else{
    if(tgt==keta){
      if((n>>keta)&1) ret = (ff(keta-1, tgt, g) + ((y*t2)%P))%P;//1
      else ret = 0;
    }else{
      if((n>>keta)&1){
        ll a = ff(keta-1, tgt, 1);//0
        ll b = (ff(keta-1, tgt, 0) + ((y*t2)%P))%P;//1
        ret = (a+b)%P;
      }else{
        ret =  ff(keta-1, tgt, 0);//0
      }
    }
  }
  //if(tgt==0) std::cout << keta << " " << ret << " " << g << '\n';
  return dp2[keta][tgt][g] = ret;
}

int main(int argc, char const *argv[]) {
  std::cin >> n;
  for(int i=1;i<=60;i++) t[i] = t[i-1] * 2;
  // 0 ~ 60
  //i bit目が立つ数の和
  ll ans = 0;
  for(int i=0;i<=60;i++){
    if(t[i]>n) break;
    f(60, i, 0);
  }
  for(int i=0;i<=60;i++){
    if(t[i]>n) break;
    ans = (ans + ff(60, i, 0))%P;
  }
  //std::cout << f(60, 0, 0) << '\n';
  //std::cout << ff(60, 0, 0) << '\n';
  std::cout << ans << '\n';
}
0