luogu P3263 [JLOI2015]有意义的字符串

luogu

兄弟会背叛你,女人会离开你,金钱会诱惑你,生活会刁难你,只有数学不会,不会就是不会,怎么学都不会。

先记\(A=\frac{b+\sqrt{d}}{2}\),出现这种东西不妨考虑他的"共轭项"",记\(B=\frac{b-\sqrt{d}}{2}\).可以发现\(A+B=b,AB=\frac{b^2-d}{4}\),并且由于\(b\bmod 2=1,d\bmod 4=1\),所以\(AB\)的值一定是个整数

现在要求\(\lfloor A^n\rfloor\),由于我们有\(A+B,AB\),所以可以考虑求\(\lfloor A^n+B^n-B^n\rfloor\),记\(f(i)=A^i+B^i\),有\(f(i)=(A+B)f(i-1)+ABf(i-2)\),所以\(f(i)\)可以矩阵快速幂求,后面的\(-B^n\),有\(-1<-B^n<1\),那只要讨论一下\(B\)是否为0以及\(n\)的奇偶性即可

#include<bits/stdc++.h>
#define LL long long
#define uLL unsigned long long

using namespace std;
const uLL mod=7528443412579576937;
uLL rd()
{
    uLL x=0,w=1;char ch=0;
    while(ch<'0'||ch>'9'){if(ch=='-') w=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+(ch^48);ch=getchar();}
    return x*w;
}
uLL pls(uLL a,uLL b){a+=b,a-=a>=mod?mod:0;return a;}
uLL mul(uLL a,uLL b){uLL an=0;while(b){if(b&1) an=pls(an,a);a=pls(a,a),b>>=1;}return an;}
struct matrix
{
    uLL a[2][2];
    matrix(){memset(a,0,sizeof(a));}
    matrix operator * (const matrix &bb) const
    {
    	matrix an;
    	for(int i=0;i<=1;++i)
    	    for(int j=0;j<=1;++j)
    		    an.a[i][j]=pls(mul(a[i][0],bb.a[0][j]),mul(a[i][1],bb.a[1][j]));
    	return an;
    }
}aa,bb;
uLL n,b,d;

int main()
{
    b=rd(),d=rd(),n=rd();
    if(!n){puts("1");return 0;}
    bool fg=(n&1)^1,f2=b*b==d;
    aa.a[0][0]=b%mod,aa.a[0][1]=f2?0:2;
    bb.a[0][0]=b%mod,bb.a[1][0]=pls(0,mod-((LL)b*(LL)b-(LL)d)/4),bb.a[0][1]=1;
    --n;
    while(n)
    {
    	if(n&1) aa=aa*bb;
    	bb=bb*bb,n>>=1;
    }
    printf("%llu\n",pls(aa.a[0][0],mod-(!f2&&fg)));
    return 0;
}
posted @ 2020-02-22 21:24  ✡smy✡  阅读(113)  评论(0编辑  收藏  举报