BZOJ 4002--有意义的字符串(矩阵乘法)
4002: [JLOI2015]有意义的字符串
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 963 Solved: 416
[Submit][Status][Discuss]
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
题目链接:
http://www.lydsy.com/JudgeOnline/problem.php?id=4002
Solution
题解PoPoQQQ 。。。膜拜orz。。。。
思路太神了!!特征方程什么的蒟蒻表示完全不会!!
注意:取模的时候注意要用快速乘。。。。
代码
#include<cstdio> #include<cstring> #include<cmath> #include<algorithm> #include<iostream> #define LL long long #define ULL unsigned long long #define mod 7528443412579576937 using namespace std; ULL qui(ULL a,ULL b){ ULL s=0; while(b){ if(b&1) s=(s+a)%mod; b>>=1; a=(a+a)%mod; } return s; } struct jz{ ULL x[2][2]; friend jz operator *(const jz &a,const jz &b){ jz tmp; for(int i=0;i<2;i++) for(int j=0;j<2;j++){ tmp.x[i][j]=0; for(int k=0;k<2;k++) tmp.x[i][j]=(tmp.x[i][j]+qui(a.x[i][k],b.x[k][j]))%mod; } return tmp; } }A,T; void pow(ULL z){ while(z){ if(z&1) T=T*A; z>>=1; A=A*A; } } int main(){ ULL b,d,n,b2,f=0; cin>>b>>d>>n; if(n==0){ printf("1\n"); return 0; } b2=qui(b,b); A.x[0][0]=b;A.x[0][1]=1;A.x[1][0]=((d-b2)/4)%mod;A.x[1][1]=0; T.x[0][0]=b;T.x[0][1]=2;T.x[1][0]=0;T.x[1][1]=0; pow(n-1); if(d!=b2&&n%2==0) f=1; T.x[0][0]=(T.x[0][0]-f+mod)%mod; cout<<T.x[0][0]<<endl; return 0; }
This passage is made by Iscream-2001.