您的位置:首页 > 其它

【BZOJ4002】[JLOI2015]有意义的字符串 数学

2017-04-25 12:19 323 查看

【BZOJ4002】[JLOI2015]有意义的字符串

Description

B 君有两个好朋友,他们叫宁宁和冉冉。有一天,冉冉遇到了一个有趣的题目:输入 b;d;n,求



Input

一行三个整数 b;d;n

Output

一行一个数表示模 7528443412579576937 之后的结果。

Sample Input

1 5 9

Sample Output

76

HINT

其中 0<b^2< = d<(b+1)2< = 10^18,n< = 10^18,并且 b mod 2=1,d mod 4=1

题解:最近数学老师刚讲的特征方程,吓人~

对于数列


我们设出特征方程x²=px+q,解出特征根x1,x2,则通项公式为



然后根据题意,令x1=

,x2=

,令A=B=1,所以得到a[0]=2,a[1]=b

然后a
我们将x1,x2带入特征方程求出p和q,然后用矩阵乘法求出a
,剩下一个

,发现它的绝对值是小于1的,那么只有在n为奇数时它才会产生-1的贡献

#include <cstdio>
#include <cstring>
#include <iostream>
#define mod 7528443412579576937ull
using namespace std;
typedef unsigned long long ll;
ll A,C,B,D,n,ans1;
typedef struct matrix
{
ll v[5][5];
}M;
M ans,x,empty;
ll pmm(ll a,ll b)
{
ll c=0;
while(b)
{
if(b&1) c=(c+a)%mod;
a=(a+a)%mod,b>>=1;
}
return c;
}
M mmul(M a,M b)
{
M c=empty;
int i,j,k;
for(i=1;i<=2;i++)	for(j=1;j<=2;j++)	for(k=1;k<=2;k++)
c.v[i][j]=(c.v[i][j]+pmm(a.v[i][k],b.v[k][j]))%mod;
return c;
}
M pm(ll y)
{
while(y)
{
if(y&1)	ans=mmul(ans,x);
x=mmul(x,x),y>>=1;
}
}
int main()
{
scanf("%llu%llu%llu",&B,&D,&n);
if(n==0)
{
printf("1");
return 0;
}
A=B,C=(D-A*A)/4;
ans.v[1][1]=A,ans.v[1][2]=2;
x.v[1][1]=A,x.v[2][1]=C,x.v[1][2]=1;
pm(n-1);
printf("%llu",ans.v[1][1]-(C&&(n%2==0)));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: