P3263 [JLOI2015] 有意义的字符串

题意

给出 \(b,d,n\),求 \(\lfloor(\frac{b+\sqrt d}2)^n\rfloor\pmod{7528443412579576937}\) 的值。
\(b,d,n\le10^{18},b\equiv1\pmod2,d\equiv1\pmod4,0\le b^2\le d<(b+1)^2\le10^{18}\)

思路

发现 \(\frac{b+\sqrt d}2\) 可以看作方程 \(x^2-bx+\frac{b^2-d}4=0\) 的一个根,由数据范围可得 \(\frac{b^2-d}4\) 是整数。变形,得 \(x^2=bx-\frac{b^2-d}4\),即 \(x^k=bx^{k-1}-\frac{b^2-d}4x^{k-2}\)。设 \(f_i=(\frac{b+\sqrt d}2)^i+(\frac{b-\sqrt d}2)^i\),那么可以根据上面的递推式和矩阵乘法快速计算出 \(f_n\),考虑计算 \((\frac{b+\sqrt d}2)^n\)。由数据范围,得 \(b-\sqrt d\le0\),先特判 \(b-\sqrt{d}=0\) 的情况。对于其祂情况,当 \(n\) 为奇数时,答案为 \(f_n\),否则答案为 \(f_n-1\)

代码

// Problem: P3263 [JLOI2015] 有意义的字符串
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P3263
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
namespace IO{
    template<typename T>
    inline void read(T&x){
        x=0;char c=getchar();bool f=0;
        while(!isdigit(c)) c=='-'?f=1:0,c=getchar();
        while(isdigit(c)) x=x*10+c-'0',c=getchar();
        f?x=-x:0;
    }
    template<typename T>
    inline void write(T x){
        if(x==0){putchar('0');return ;}
        x<0?x=-x,putchar('-'):0;short st[50],top=0;
        while(x) st[++top]=x%10,x/=10;
        while(top) putchar(st[top--]+'0');
    }
    inline void read(char&c){c=getchar();while(isspace(c)) c=getchar();}
    inline void write(char c){putchar(c);}
    inline void read(string&s){s.clear();char c;read(c);while(!isspace(c)&&~c) s+=c,c=getchar();}
    inline void write(string s){for(int i=0,len=s.size();i<len;i++) putchar(s[i]);}
    template<typename T>inline void write(T*x){while(*x) putchar(*(x++));}
    template<typename T,typename...T2> inline void read(T&x,T2&...y){read(x),read(y...);}
    template<typename T,typename...T2> inline void write(const T x,const T2...y){write(x),putchar(' '),write(y...),sizeof...(y)==1?putchar('\n'):0;}
}using namespace IO;
#define LL __int128
const LL mod=7528443412579576937;
LL b,d,n;
struct Matrix{
    LL a[5][5];
    Matrix(){memset(a,0,sizeof(a));}
    friend Matrix operator*(const Matrix a,const Matrix b){
        Matrix c;
        for(int k=1;k<=3;k++) for(int i=1;i<=3;i++) for(int j=1;j<=3;j++) c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j]%mod)%mod;
        return c;
    }
};
signed main(){
    read(b,d,n);
    Matrix base,f;
    base.a[1][1]=b,base.a[1][2]=1;
    base.a[2][1]=(-((b*b-d)/4%mod)+mod)%mod,base.a[2][2]=0;
    f.a[1][1]=b,f.a[1][2]=2;
    if(n==0){write(1);return 0;}
    LL c=n-1;
    while(c){
        if(c&1) f=f*base;
        base=base*base;
        c>>=1;
    }
    LL ans=f.a[1][1];
    if(b*b==d){write(ans);return 0;}
    if(n%2==0) ans=(ans-1+mod)%mod;
    write(ans);
    return 0;
}
posted @ 2026-08-13 22:18  Link-Cut_Trees  阅读(8)  评论(0)    收藏  举报