Description
Input
一行三个整数b, d, n。
Output
一行一个数表示模7528443412579576937 之后的结果。
Sample Input
输入1:1 5 9输入2:11 125 6715504
Sample Output
输出1:76输出2:1499928102740042526
Data Constraint
好吧。一直没看懂题目名到底有意义在哪= =
进入正题
首先我们发现(b+sqrt(d))/2可以是某个方程的解,它符合(-b+sqrt(b*b-4ac))/2a的形式。
我们发现这个方程是x^2=bx+(d-b^2)/4;
我们假设一个数列f[n]=((b+sqrt(d))/2)^n;
由刚才的方程可得f[n]满足f[n]=bf[n-1]+(d-b^2)/4*f[n-2]
所以对于((b+sqrt(d))/2的n次方我们可以矩乘快速幂求得。
但实数直接上mod是会挂的!
我们接着发现方程另外一根为((b-sqrt(d))/2;
那么它同样满足上面的递推式
我们设h[n]=((b+sqrt(d))/2)^n+((b+sqrt(d))/2)^n,那么h[n]同样满足递推式,而且h[n]是整数!!!
又因为((b+sqrt(d)/2)^n绝对值小于1,所以它的影响我们可以直接特判,
就这样,
另外,由于mod的数太大,乘法我们要用快速乘实现
#include<cstdio> #include<cstdlib> #include<algorithm> #include<cmath> #include<cstring> using namespace std; typedef long long ll; struct Matrix{ ll a[4][4]; int n,m; }dw,dl,y; ll mo=7528443412579576937ll; ll ans,n,b,d; ll add(ll a,ll b) { ll lef; lef=mo-a; if(b<=lef)a=a+b; else a=b-lef; return a; } ll mul(ll a,ll b) { ll l; l=0; while(b){ if(b%2==1)l=add(l,a); a=add(a,a); b/=2; } return l; } Matrix operator *(Matrix a,Matrix b) { Matrix c; int i,j,k; memset(c.a,0,sizeof(c.a)); c.n=a.n;c.m=b.m; for(i=1;i<=a.n;i++) for(j=1;j<=b.m;j++){ c.a[i][j]=0; for(k=1;k<=a.m;k++)c.a[i][j]=add(c.a[i][j],mul(a.a[i][k],b.a[k][j])); } return c; } Matrix mi(Matrix x,ll z) { Matrix l; l.n=l.m=2; memset(l.a,0,sizeof(l.a)); l.a[1][1]=1;l.a[2][2]=1; while(z){ if(z%2==1)l=l*x; x=x*x; z/=2; } return l; } int main() { scanf("%lld%lld%lld",&b,&d,&n); dw.a[1][1]=0;dw.a[1][2]=(d-b*b)/4; dw.a[2][1]=1;dw.a[2][2]=b; dw.n=dw.m=2; dl=mi(dw,n); if(n==0)ans=1; else{ ans=mul(dl.a[1][1],2); ans=add(ans,mul(b,dl.a[2][1])); if(d!=b*b&&n%2==0)ans--; if(ans<0)ans+=mo; } printf("%lld\n",ans); }
时间: 2024-10-24 23:50:59