代码改变世界

Count(矩阵快速幂)

2019-08-18 20:03  木木王韦  阅读(251)  评论(0)    收藏  举报

Count

Farmer John有n头奶牛.
某天奶牛想要数一数有多少头奶牛,以一种特殊的方式:
第一头奶牛为1号,第二头奶牛为2号,第三头奶牛之后,假如当前奶牛是第n头,那么他的编号就是2倍的第n-2头奶牛的编号加上第n-1头奶牛的编号再加上自己当前的n的三次方为自己的编号.
现在Farmer John想知道,第n头奶牛的编号是多少,估计答案会很大,你只要输出答案对于123456789取模.
Input
第一行输入一个T,表示有T组样例
接下来T行,每行有一个正整数n,表示有n头奶牛 (n>=3)
其中,T=104,n<=1018
Output
共T行,每行一个正整数表示所求的答案
Sample Input
5
3
6
9
12
15
Sample Output
31
700
7486
64651
527023

!!!!!败在了const 超时超的怀疑人生,
以下是百度百科const的作用:
const
const是一个C语言(ANSI C)的关键字,具有着举足轻重的地位。它限定一个变量不允许被改变,产生静态作用。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一定帮助。另外CONST在其它编程语言中也有出现,例如Pascal、C++、PHP5、B#.net、HC08 C、C#等。

const long &i=10; /由于编译器的优化,使得在const long i=10; 时i不被分配内存,而是已10直接代入以后的引用中,以致在以后的代码中没有错误,为达到说教效 果,特别地用&i明确地给出了i的内存分配。不过一旦你关闭所有优化措施,即使const long i=10;也会引起后面的编译错误。/

ac代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<map>
using namespace std;

int t;
long long int n;
int f=6;
long long int mod=123456789;
struct node{
	long long int m[11][11];
};

node a,b,c;
node mul(node a,node b){
	node ans;
	memset(ans.m,0,sizeof(ans.m));
	for(int i=1;i<=f;i++){
		for(int j=1;j<=f;j++){
			for(int k=1;k<=f;k++){
				ans.m[i][j]=(ans.m[i][j]+a.m[i][k]*b.m[k][j]%mod)%mod;
			}
		}
	}
	return ans;
}

node ksm(node a,long long int b){
	//cout<<"&&&"<<endl;
	node res;
	memset(res.m,0,sizeof(res.m));
	for(int i=1;i<=f;i++){
		res.m[i][i]=1;
	}
	while(b){
		if(b&1){
			res=mul(res,a);
		}
		b>>=1;
		a=mul(a,a);
	}
	return res;
}
int main(){
//	ios::sync_with_stdio(0);
//	cin.tie(0),cout.tie(0);
			memset(a.m,0,sizeof(a.m));
			memset(b.m,0,sizeof(b.m));
			b.m[1][1]=2;
			b.m[2][1]=1;
			b.m[3][1]=27;
			b.m[4][1]=9;
			b.m[5][1]=3;
			b.m[6][1]=1;
			a.m[1][1]=1;
			a.m[1][2]=2;
			a.m[1][3]=1;
			a.m[2][1]=1;
			a.m[3][3]=1;
			a.m[3][4]=3;
			a.m[3][5]=3;
			a.m[3][6]=1;
			a.m[4][4]=1;
			a.m[4][5]=2;
			a.m[4][6]=1;
			a.m[5][5]=1;
			a.m[5][6]=1;
			a.m[6][6]=1;
	
	scanf("%d",&t);
	while(t--){
		scanf("%lld",&n);
		
				c=ksm(a,n-2);
			
				
				
			c=mul(c,b);
		
//			for(int i=1;i<=f;i++){
//				for(int j=1;j<=f;j++){
//					cout<<c.m[i][j]<<" ";
//				}
//				cout<<endl;
//			}

		printf("%lld\n",c.m[1][1]%mod);
	}
	
	return 0;
}
/*
20
4
234325
23534534
235325452245
3252454325235
213534534524524
3252345245234532
325425235235235245
235234523524523423
32423423423423
234324234535324
324324235435235
32543252353252345
235234542543332
2345235235233243
325455322345435
2354354353432423
23454332354543
45434343543534
643453423652654

*/