Codeforces Round #307 (Div. 二) D. GukiZ and Binary Operations(数学)
Codeforces Round #307 (Div. 2) D. GukiZ and Binary Operations(数学)
每一位分开考虑,乘法计数原理,用f[i]表示i个数的某一位进行上述操作为0的方案数,很容易发现f是裴波拉契数列。跪在mod为1和k大于等于2^l上,细心啊!!!
#include <bits/stdc++.h> using namespace std; typedef long long ll; int mod; // f[i+1] += f[i] (a[i+1] == 0) // f[i+1] += f[i-1] (a[i+1] == 1) struct Matrix { ll a[2][2]; Matrix operator * (const Matrix & t) const { Matrix c; memset(c.a,0,sizeof(c.a)); for(int i = 0; i < 2; i++) { for(int j = 0; j < 2; j++) { for(int k = 0; k < 2; k++) { c.a[i][j] += a[i][k] * t.a[k][j]; c.a[i][j] %= mod; } } } return c; } }; Matrix gao(ll n) { Matrix res = {1,0,0,1}; Matrix base = {1,1,1,0}; while(n > 0) { if(n & 1) res =res * base; n >>= 1; base = base * base; } Matrix f = {1,1,0,0}; return f * res; } ll quick(ll n) { ll res = 1,base = 2; //cout << n<<endl; while(n > 0) { if(n & 1)res = (res * base) % mod; n >>= 1; base = (base * base) % mod; } return res; } int main() { ios_base::sync_with_stdio(false); ll n,k,l; while(cin>>n>>k>>l>>mod) { ll res = 1,t = gao(n).a[0][0]; ll all = quick(n); for(int i = 0; i < l; i++) { if(k & 1) { res = res * (all - t + mod) % mod; }else { res = res * t % mod; } k >>= 1; } if(k)res = 0; cout<<res%mod<<"\n"; } return 0; }