华丽的A+B |
Time Limit: 1 Seconds Memory Limit: 32768 K Total Submit:94 Accepted:10 |
Description 由于没人辅导,wekooo学的东西总是那么地散,最近他又迷上了方程求解问题. Input 有多组测试数据,每行一个输入一个正整数N(1<=N<=10^9). Output 对应输入每行输出一个解,a+b的值.为了避免高精度我们将结果对2^64取模. Sample Input 6 28 496 8128 Sample Output 21 832040 17929816685963478168 6075550357158932568 Source |
生成几组小数据,马上得到规律,a+b满足
f[1]=2;
f[2]=3;
f[3]=5;
....
f[n]=f[n-1]+f[n-2](n>=3)
由于题目需要对2^64取mod
所以直接使用矩阵乘法就可以快速的解决
f[n] 1 1 f[n-1]
= *
f[n-1] 1 0 f[n-2]
一直化下去可以得到实际上:
f[n] 1 1 f[2]
为 的n-2次方 *
f[n-1] 1 0 f[1]
矩阵乘法使用二分
同时其他的类似的递推也可以使用矩阵-__________________-
以下是代码:
- #include <iostream>
- using namespace std;
- struct mc
- {
- unsigned long long a[2][2];
- mc operator*(const mc& m)
- {
- mc n;
- int i,j,k;
- for(i=0;i<2;i++)
- for(j=0;j<2;j++)
- n.a[i][j]=0;
- for(i=0;i<2;i++)
- for(j=0;j<2;j++)
- for(k=0;k<2;k++)
- {
- n.a[i][j]+=a[i][k]*m.a[k][j];
- }
- return n;
- }
- }A;
- mc pow(int k,mc* mat)
- {
- mc temp;
- if(k==1) return (*mat);
- temp=(*mat)*(*mat);
- if(k&1)
- return pow(k/2,&temp)*(*mat);
- else
- return pow(k/2,&temp);
- }
- int main()
- {
- int n;
- mc kk;
- A.a[0][0]=1;
- A.a[0][1]=1;
- A.a[1][0]=1;
- A.a[1][1]=0;
- while(cin>>n)
- {
- if(n==1)
- {
- cout<<2<<endl;
- continue;
- }
- if(n==2)
- {
- cout<<3<<endl;
- continue;
- }
- kk=pow(n-2,&A);
- cout<<kk.a[0][0]*3+kk.a[0][1]*2<<endl;
- }
- }