51Nod-1436-方程的解数

来源:互联网 发布:python findall语法 编辑:程序博客网 时间:2024/05/18 09:29

ACM模版

描述

描述

题解

既然讨论区有如此详尽的题解,我何不直接拿过来呢?

描述

这里说到无解的情况,其实也就是当 ai 取值总是小于 k 时,无解,换种说法就是 k2l,这里存在溢出的问题,尽管使用 ULL,同样无法避免当 l64 时的溢出,所以直接特判一下就行了。

代码

#include <iostream>#define mod(a, m) ((a) % (m) + (m)) % (m)using namespace std;typedef long long ll;const int MAGIC = 64;ll n, k, l, m;struct matrix{    ll c[2][2];} a;ll f[2];void ans_cf(matrix a){    f[0] = mod(a.c[0][0] + a.c[1][0], m);    f[1] = mod(a.c[0][1] + a.c[1][1], m);}matrix matrix_cf(matrix a, matrix b){    matrix ans;    for (int i = 0; i < 2; i++)    {        for (int j = 0; j < 2; j++)        {            ans.c[i][j] = 0;            for (int k = 0; k < 2; k++)            {                ans.c[i][j] += a.c[k][i] * b.c[j][k];                ans.c[i][j] = mod(ans.c[i][j], m);            }        }    }    return ans;}matrix matrix_pow(matrix a, ll n){    matrix ans;    ans.c[0][0] = ans.c[1][1] = 1;    ans.c[0][1] = ans.c[1][0] = 0;    while (n)    {        if (n & 1)        {            ans = matrix_cf(ans, a);        }        n = n >> 1;        a = matrix_cf(a, a);    }    return ans;}ll qpow(ll a, ll b){    ll ans = 1;    while (b)    {        if (b & 1)        {            ans = mod(ans * a, m);        }        b = b >> 1;        a = mod(a * a, m);    }    return ans;}void init(){    a.c[0][0] = a.c[0][1] = a.c[1][0] = 1;    a.c[1][1] = 0;}int main(int argc, const char * argv[]){    cin >> n >> k >> l >> m;    unsigned long long t = 1ULL << l;    if (m == 1 || (k >= t && l != MAGIC))    {        cout << 0 << '\n';        return 0;    }    init();    a = matrix_pow(a, n);    ans_cf(a);    ll x = f[0], y = mod(qpow(2, n) - x, m);    int cnt_0 = 0, cnt_1 = 0;    while (k)    {        if (k % 2)        {            cnt_1++;        }        else        {            cnt_0++;        }        k >>= 1;    }    cnt_0 += l - cnt_0 - cnt_1;    ll ans = mod(mod(qpow(x, cnt_0), m) * mod(qpow(y, cnt_1), m), m);    cout << ans << '\n';    return 0;}
原创粉丝点击