BZOJ4002 [JLOI2015] Meaningful String [Math + Moment Multiplication]

topic link

BZOJ4002

answer

It is easy to think that \(\frac{b + \sqrt{d}}{2}\) is the quadratic function \(x^2 - bx + \frac{b^2 - d}{4} = 0\ ) One
, then there is
\[x^2 = bx - \frac{b^2 - d}{4}\]
multiply a \(x^n\)
\[x^n = bx^{n - 1} - \frac{b^2 - d}{4}x^{n - 2}\]

Looking at the subject conditions again, we can find that \(|b^2 - d| < 1\) , so obviously another root is needed \(\frac{b - \sqrt{d}}{2}\)
We set
\ [f[i] = (\frac{b + \sqrt{d}}{2})^i + (\frac{b - \sqrt{d}}{2})^i\]
Then there is
\[ f[i] = bf[i - 1] - \frac{b^2 - d}{4}f[i - 2]\]
Moment multiplication can be calculated by optimizing it \(f[n]\)
\[ans = f[n] - (\frac{b - \sqrt{d}}{2})^n\]
The latter thing is less than \(1\) , so we only need to discuss its positive and negative to determine Which side should the output be rounded to?

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ULL unsigned long long int
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000;
const ULL P = 7528443412579576937ll;
ULL mul(ULL a,ULL b){
    ULL re = 0; b = (b % P + P) % P; a = (a % P + P) % P;
    for (; b; b >>= 1,a = (a + a) % P) if (b & 1) re = (re + a) % P;
    return re;
}
struct Matrix{
    ULL s[2][2]; int n,m;
    Matrix(){memset(s,0,sizeof(s)); n = m = 0;}
};
inline Matrix operator *(const Matrix& a,const Matrix& b){
    Matrix c;
    if (a.m != b.n) return c;
    c.n = a.n; c.m = b.m;
    for (int i = 0; i < c.n; i++)
        for (int j = 0; j < c.m; j++)
            for (int k = 0; k < a.m; k++)
                c.s[i][j] = ((c.s[i][j] + mul(a.s[i][k],b.s[k][j])) % P + P) % P;
    return c;
}
inline Matrix qpow(Matrix a,ULL b){
    Matrix c; c.n = c.m = a.n;
    for (int i = 0; i < c.n; i++) c.s[i][i] = 1;
    for (; b; b >>= 1,a = a * a)
        if (b & 1) c = c * a;
    return c;
}
int main(){
    ULL b,d,n;
    cin >> b >> d >> n;
    if (n == 0){puts("1"); return 0;}
    Matrix A,F,Fn;
    A.n = A.m = 2;
    A.s[0][0] = (b % P + P) % P; A.s[0][1] = (((d - b * b) / 4 % P) + P) % P;
    A.s[1][0] = 1; A.s[1][1] = 0;
    F.n = 2; F.m = 1;
    F.s[0][0] = (b % P + P) % P; F.s[1][0] = 2;
    Fn = qpow(A,n - 1) * F;
    if (b * b != d && !(n & 1)) cout << ((Fn.s[0][0] - 1) % P + P) % P << endl;
    else cout << Fn.s[0][0] << endl;
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325383560&siteId=291194637