Facebook
From amsen, 4 Years ago, written in C++.
Embed
Download Paste or View Raw
Hits: 468
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. typedef long long ll;
  6.  
  7. #define int long long
  8.  
  9. const int N = 60, MOD = 1e9+7;
  10.  
  11. int add(ll a, int b){
  12.     return (a + b) % MOD;
  13. }
  14.  
  15. int mul(ll a, int b){
  16.     return a * b % MOD;
  17. }
  18.  
  19. void sadd(int &a, int b){
  20.     a = add(a, b);
  21. }
  22.  
  23. void smul(int &a, int b){
  24.     a = mul(a, b);
  25. }
  26.  
  27. int bp(int a, int b){
  28.     if(b == 0)
  29.         return 1;
  30.     int x = bp(a, b/2);
  31.     smul(x, x);
  32.     return b&1 ? mul(x, a) : x;
  33. }
  34.  
  35. int inv(int x){
  36.     return bp(x, MOD-2);
  37. }
  38.  
  39. struct dat{
  40.     int sum[4][4], cnt[4][4];
  41.     dat(){
  42.         memset(sum, 0, sizeof sum);
  43.         memset(cnt, 0, sizeof cnt);
  44.     }
  45. } dp[N];
  46.  
  47. int mp[4][4];
  48.  
  49. dat merge(const dat &f, const dat &s){
  50.     dat ret;
  51.     for(int ll=0 ; ll<4 ; ll++)
  52.         for(int lr=0 ; lr<4 ; lr++)
  53.             for(int rl=0 ; rl<4 ; rl++)
  54.                 for(int rr=0 ; rr<4 ; rr++){
  55.                     sadd(ret.cnt[ll][rr], mul(f.cnt[ll][lr], s.cnt[rl][rr]));
  56.                     int cur = mul(f.cnt[ll][lr], s.sum[rl][rr]);
  57.                     sadd(cur, mul(f.sum[ll][lr], s.cnt[rl][rr]));
  58.                     int cnt = mp[lr][rl];
  59.                     sadd(cur, mul(cnt, mul(f.cnt[ll][lr], s.cnt[rl][rr])));
  60.                     sadd(ret.sum[ll][rr], cur);
  61.                 }
  62.     return ret;
  63. }
  64.  
  65. void init();
  66.  
  67. signed main(){
  68.         ios_base::sync_with_stdio(false);cin.tie(NULL);
  69.     init();
  70.     for(int i=0 ; i<4 ; i++)
  71.         dp[0].cnt[i][i] = 1;
  72.     for(int bt=1 ; bt<N ; bt++)
  73.         dp[bt] = merge(dp[bt-1], dp[bt-1]);
  74.     ll n;cin >> n;
  75.     dat ans = dp[0];
  76.     for(int i=0 ; i<N ; i++)
  77.         if((n-1) & (1LL << i))
  78.             ans = merge(ans, dp[i]);
  79.     int out = 0;
  80.     for(int l=0 ; l<4 ; l++)
  81.         for(int r=0 ; r<4 ; r++){
  82.             int cur = mul(ans.cnt[l][r], 1 + (bool(r&1) != bool(r&2)));
  83.             sadd(cur, ans.sum[l][r]);
  84.             sadd(out, cur);
  85.         }
  86.     //cerr << out << "\n";
  87.     cout << mul(out, inv(bp(2, 2LL*n))) << "\n";
  88. }
  89.  
  90. void init(){
  91.     mp[0][0] = 0;
  92.     mp[0][1] = 0;
  93.     mp[0][2] = 0;
  94.     mp[0][3] = 1;
  95.     mp[1][0] = 1;
  96.     mp[1][1] = 0;
  97.     mp[1][2] = 2;
  98.     mp[1][3] = 1;
  99.     mp[2][0] = 1;
  100.     mp[2][1] = 2;
  101.     mp[2][2] = 0;
  102.     mp[2][3] = 1;
  103.     mp[3][0] = 1;
  104.     mp[3][1] = 0;
  105.     mp[3][2] = 0;
  106.     mp[3][3] = 0;
  107. }
  108.  
  109.