# Codeforces 551 D. GukiZ and Binary Operations

## Description

$n,k \leq 2^{60},l \leq 60$

## Solution

\left\{ \begin{aligned} f_{i,0} & =f_{i-1,0}+f_{i-1,1} \\ f_{i,1} & =f_{i-1,0}\\ \end{aligned} \right.

$ans=\sum\limits_{i=1}^{n-1}f_{i-1} \times 2^{n-i-1}$

$g_n=\sum\limits_{i=1}^{n-1}f_{i-1} \times 2^{n-i-1}$

$g_i=2 \times g_{i-1}+f_{i-1}$

$\begin{bmatrix} g_{i-1} & f_{i-2} & f_{i-1} \end{bmatrix} \times \begin{bmatrix} 2 & 0 & 0\\ 0 & 0 & 1\\ 1 & 1 & 1\\ \end{bmatrix} \text{=} \begin{bmatrix} g_{i} & f_{i-1} & f_{i} \end{bmatrix}$

## Discovery（戴睿同学的做法）

$\sum\limits_{i=1}^{n-1}f_{i-1} \times 2^{n-i-1}=2^n-f_{n+1}$

$\sum\limits_{i=1}^{n-1}f_{i-1} \times 2^{n-i-1}= \sum\limits_{i=0}^{n-2}f_{i} \times 2^{n-i-2}$可以看做斐波那契数列与等比数列的卷积，那么左边的生成函数封闭表达式即为

$\dfrac{1}{1-x-x^2} \cdot \dfrac{1}{1-2x}$

$\dfrac{x^2}{(1-x-x^2)(1-2x)}$

## 推斐波那契数列的通项公式

$F(x)=f_0+f_1x+f_2x^2+f_3x^3+ \cdots$

$xF(x)=f_0x+f_1x^2+f_2x^3+f_3x^4+ \cdots$

$x^2F(x)=f_0x^2+f_1x^3+f_2x^4+f_3x^5+ \cdots$

$F(x)-xF(x)=f_0+f_0x^2+f_1x^3+\cdots=x^2F(x)+1$

$F(x)=\dfrac{1}{1-x-x^2}$

$F(x)=\dfrac{a}{1-\phi_1x} + \dfrac{b}{1-\phi_2x}$

$a(1-\phi_2x)+b(1-\phi_1x)=1$恒成立

\left\{ \begin{aligned} &a\phi_2+b\phi_1 = 0\\ &a+b=1\\ \end{aligned} \right.

\left\{ \begin{aligned} &a=\dfrac{\phi_1}{\phi_1-\phi_2}\\ &b=-\dfrac{\phi_2}{\phi_1-\phi_2}\\ \end{aligned} \right.

q'z

$F(x)=\dfrac{1}{\phi_1-\phi_2}(\dfrac{\phi_1}{1-\phi_1x}-\dfrac{\phi_2}{1-\phi_2x})$

$f_n=\dfrac{1}{\sqrt 5}((\dfrac{\sqrt 5+1}{2})^n+(\dfrac{\sqrt 5-1}{2})^n)$

## Code

/*DennyQi 2019*/
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#define int long long
using namespace std;
const int N = 100010;
const int P = 998244353;
const int INF = 0x3f3f3f3f;
int x(0),w(1); char c = getchar();
while(c^'-' && (c<'0' || c>'9')) c = getchar();
if(c=='-') w = -1, c = getchar();
while(c>='0' && c<='9') x = (x<<3)+(x<<1)+c-'0', c = getchar(); return x*w;
}
int n,k,l,m,Fn,ans,cur,y;
inline int mul(const int& a, const int& b){ return 1ll*a*b%m; }
inline int add(const int& a, const int& b){ return (a+b>=m)?a+b-m:a+b; }
inline int sub(const int& a, const int& b){ return (a-b<0)?a-b+m:a-b; }
struct matrix{
int a[2][2];
matrix operator * (const matrix& X) const{
matrix res;
for(int i = 0; i < 2; ++i){
for(int j = 0; j < 2; ++j){
res.a[i][j] = 0;
for(int k = 0; k < 2; ++k){
}
}
}
return res;
}
};
matrix x,res;
inline int ksm(int x, int y){
int res = 1;
while(y>0){
if(y&1) res = mul(res,x);
y >>=1, x = mul(x,x);
}
return res;
}
#undef int
int main(){
#define int long long
// freopen("file.in","r",stdin);
if(l<=62&&(1ll<<l)<=k){
puts("0");
return 0;
}
res.a[0][0] = res.a[1][1] = 1;
x.a[0][1] = x.a[1][0] = x.a[1][1] = 1;
y = n;
while(y>0){
if(y&1) res = res*x;
y >>= 1, x = x*x;
}
ans = 1;
for(int i = 1; i <= l; ++i){
cur = (k&1);
k >>= 1;
if(cur == 0){
ans = mul(ans,Fn);
}else{
ans = mul(ans,sub(ksm(2,n),Fn));
}
}
printf("%lld\n",ans%m);
return 0;
}
posted @ 2020-12-04 22:16  DennyQi  阅读(78)  评论(0编辑  收藏  举报