哈哈哈,失踪人员回归。最近总是在忙一些乱七八糟的事情,终于有了一段空闲时间可以刷刷题了。学姐给我准备了kuangbin先生的矩阵专题,作为我的矩阵终结专题。(初学者请先看我的矩阵专题前三篇)
第一题 CodeForces 450B
分析:这道题看似是一道矩阵题,但是实际上是一道模拟题。看题目给出的公式 f(i)=f(i-1)+f(i+1),i>=2,那么转换一下得到了f(i)=f(i-1)-f(i-2),i>=3,当然这题可以使用矩阵快速幂来算,但是多此一举。不妨将f(1)=x f(2)=y代进去计算前几项,那么依次得到 x y y-x -x -y x-y x y ......,我们发现这个数列是有循环节的,而且必定为6,那么只需要计算前六个,n取一下模即可得到答案。注意:x y可能是负数,但是答案一定得是非负整数。
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          200000+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
ll dat[10];
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	ll n;
	scanf("%I64d %I64d",&dat[1],&dat[2]);
	dat[1]=(dat[1]+mod)%mod;
	dat[2]=(dat[2]+mod)%mod;
	scanf("%I64d",&n);
	dat[0]=(dat[1]-dat[2]+mod)%mod;
	for(int i=3;i<6;i++)
		dat[i]=(dat[i-1]-dat[i-2]+mod)%mod;
	printf("%I64d\n",dat[n%6]);
    return 0;
}
题目大意:给你一个矩阵,矩阵第一行中,第一个数为空,之后的数就是233,2333,23333。。。一直轮下去。然后,矩阵第一列上,第一个数为空(即第一行第一列的那个数为空),之后的所有数会给出。接着,告诉你这个矩阵其他元素都是按照maze[i][j]=maze[i-1][j]+maze[i][j-1]的规律来计算的,让你求出矩阵右下角的数是多少。
分析:一开始没有往矩阵方面想,前段时间数论做多了之后很容易就发现最后的maze[n][m]的数可以通过已知的数乘一个数(满足一个组合数,杨辉三角),然后相加得到。虽然我公式推出来了,但是复杂度太高,而且写起来还麻烦,就被我pass了,有兴趣的朋友可以自己推一推写一写。然后回过去想矩阵做法的话,立刻就想到了(提示n的值很大,但是m的值不大)。将输入的23(第一个23是补充上去的,为了和之后的23333对齐),maze[1][0],maze[2][0],maze[3][0],......作为初始值,根据公式很容易看出转换的矩阵,除了第一个233是前一个23乘10加3,其他的都是maze[i][j]=maze[i-1][j]+maze[i][j-1]。
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          10+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
ll mul(ll a,ll b){
	ll ans=0;
	while(b){
		if(b&1)ans=(ans+a)%mod;
		a=(a+a)%mod;
		b>>=1;
	}
	return ans;
}
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%10000007;
		return ans;
	}
};
matrix qlow(matrix a,int n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int n,m;
	while(~scanf("%d %d",&n,&m)){
		matrix ans;
		ans.init(n+2);
		for(int i=1;i<=n;i++)
			scanf("%lld",&ans.maze[0][i]);
		ans.maze[0][0]=23;
		ans.maze[0][n+1]=1;
		matrix ant;
		ant.init(n+2);
		for(int i=0;i<=n;i++)
			ant.maze[0][i]=10,ant.maze[n+1][i]=3;
		ant.maze[n+1][n+1]=1;
		for(int i=1;i<=n;i++)
			for(int j=i;j<=n;j++)
				ant.maze[i][j]=1;
		ant=qlow(ant,m);
		ans=ans*ant;
		printf("%lld\n",ans.maze[0][n]);
	}
    return 0;
}
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn         	0+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
int m;
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%m;
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int n;
	while(~scanf("%d %d",&n,&m)){
		matrix ant;
		ant.init(2);
		ant.maze[0][0]=4;
		ant.maze[1][0]=2;
		ant.maze[1][1]=1;
		ant=qlow(ant,n/2);
		ll ans=ant.maze[1][0];
		if(n&1)ans=(ans*2+1)%m;
		cout<<ans<<endl;
	}
    return 0;
}
我知道读者肯定没有看懂,无妨,请转到这位大神的博客,他写得很好,这里我贴下我的代码
http://www.cnblogs.com/AOQNRMGYXLMV/p/5256508.html
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          150+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
//const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
int n,m,base,score;
unsigned int d[40][10];
struct matrix{
	int n;
	unsigned int maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]+=maze[i][k]*rhs.maze[k][j];
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
unsigned int solve(){
	scanf("%d %d",&base,&score);
	if(base==2)return 1;
	m=(base-1)*(base-1);
	n=base*m;
	for(int i=1;i<base;i++)
		d[0][i]=1;
	for(int i=1;i<m;i++)
		for(int j=0;j<base;j++){
			d[i][j]=0;
			for(int k=0;k<base;k++)
				if(k!=j&&(j-k)*(j-k)<=i){
					d[i][j]+=d[i-(j-k)*(j-k)][k];
				}
		}
	/*for(int i=0;i<m;i++){
		for(int j=0;j<base;j++)
			cout<<d[i][j]<<" ";
		cout<<endl;
	}*/
	if(score<m){
		unsigned int cnt=0;
		for(int i=0;i<base;i++)
			cnt+=d[score][i];
		return cnt;
	}
	matrix ans;
	ans.init(n);
	for(int i=0;i<m;i++)
		for(int j=0;j<base;j++)
			ans.maze[0][i*base+j]=d[i][j];
	matrix ant;
	ant.init(n);
	for(int j=0;j<(m-1)*base;j++)
		ant.maze[j+base][j]=1;
	for(int j=(m-1)*base;j<n;j++){
		int ss=m,bb=j%base;
			for(int i=0;i<base;i++)
				if(i!=bb){
					int sst=ss-(i-bb)*(i-bb);
					if(sst>=0){
						ant.maze[sst*base+i][j]=1;
					}
				}
	}
	/*for(int i=0;i<n;i++){
		for(int j=0;j<n;j++)
			cout<<ant.maze[i][j]<<" ";
		cout<<endl;
	}*/
	ant=qlow(ant,score-m+1);
	ans=ans*ant;
	unsigned int cnt=0;
	for(int i=0;i<base;i++)
		cnt+=ans.maze[0][n-1-i];
	return cnt;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int t;
	scanf("%d",&t);
	for(int cas=1;cas<=t;cas++)
		printf("Case %d: %u\n",cas,solve());
    return 0;
}
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          0+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
//const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
struct matrix{
	int n;
	int maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%6;
		return ans;
	}
};
matrix qlow(matrix a,int n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int A[1010][10];
int B[10][1010];
int C[1010][10];
int D[1010][1010];
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int n,k;
	while(scanf("%d %d",&n,&k),n||k){
		for(int i=0;i<n;i++)
			for(int j=0;j<k;j++)
				scanf("%d",&A[i][j]);
		for(int i=0;i<k;i++)
			for(int j=0;j<n;j++)
				scanf("%d",&B[i][j]);
		matrix ans;
		ans.init(k);
		for(int i=0;i<k;i++)
			for(int j=0;j<k;j++)
				for(int h=0;h<n;h++)
					ans.maze[i][j]=(ans.maze[i][j]+B[i][h]*A[h][j])%6;
		ans=qlow(ans,n*n-1);
		for(int i=0;i<n;i++)
			for(int j=0;j<k;j++){
				C[i][j]=0;
				for(int h=0;h<k;h++)
					C[i][j]=(C[i][j]+A[i][h]*ans.maze[h][j])%6;
			}
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++){
				D[i][j]=0;
				for(int h=0;h<k;h++)
					D[i][j]=(D[i][j]+C[i][h]*B[h][j])%6;
			}
		ll ant=0;
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				ant+=D[i][j];
		cout<<ant<<endl;
	}
    return 0;
}
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          50+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%1000;
		return ans;
	}
};
matrix qlow(matrix a,int n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int t;
	scanf("%d",&t);
	while(t--){
		int n,r;
		scanf("%d %d",&n,&r);
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			scanf("%lld",&ans.maze[0][i]);
		matrix ant;
		ant.init(n);
		for(int i=0;i<n;i++){
			int k;
			scanf("%d",&k);
			while(k--){
				int a;
				scanf("%d",&a);
				ant.maze[a][i]=1;
			}
		}
		ant=qlow(ant,r);
		ans=ans*ant;
		int cnt=0;
		for(int i=0;i<n;i++){
			if(cnt)putchar(' ');
			cnt=1;
			printf("%lld",ans.maze[0][i]);
		}
		puts("");
	}
    return 0;
}
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          0+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
ll m;
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%m;
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int t;
	scanf("%d",&t);
	while(t--){
		ll a,b,n;
		scanf("%lld %lld %lld %lld",&a,&b,&n,&m);
		if(n==0){
			printf("%lld\n",a);
			continue;
		}
		if(m==1)m=10;
		else if(m==2)m=100;
		else if(m==3)m=1000;
		else m=10000;
		//cout<<m<<endl;
		matrix ans;
		ans.init(2);
		ans.maze[0][1]=ans.maze[1][0]=ans.maze[1][1]=1;
		ans=qlow(ans,n-1);
		printf("%lld\n",(a*ans.maze[0][1]+b*ans.maze[1][1])%m);
	}
    return 0;
}
分析:以前在poj上做过一个几乎一模一样的,可以用二分做,也可以直接矩阵快速幂。(不明白去看一前面的矩阵专题)注意一下,结束条件。
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          90+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%10;
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int n;
	ll k;
	while(scanf("%d %lld",&n,&k),n){
		matrix ans;
		ans.init(n<<1);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++){
				scanf("%lld",&ans.maze[i][j]);
				ans.maze[i][j]%=10;
				ans.maze[i][j+n]=ans.maze[i][j];
			}
		for(int i=0;i<n;i++)ans.maze[i+n][i+n]=1;
		ans=qlow(ans,k);
		for(int i=0;i<n;i++){
			int cnt=0;
			for(int j=0;j<n;j++){
				if(cnt)putchar(' ');
				cnt=1;
				printf("%lld",ans.maze[i][j+n]);
			}
			puts("");
		}
		puts("");
	}
    return 0;
}
分析:题目给你a+b与ab的值,让你求出a^n+b^n。题目描述很简单,解法也比较好想到。对于a^n+b^n,那么考虑a^(n-1)+b^(n-1),两者之间的联系是a^n+b^n = [a^(n-1)+b^(n-1)] * (a + b) - ab * (a^(n-2) + b^(n-2)) , n>=2。那么可以构造矩阵
注意:-ab要使用加分逆元变成正数!还有p=0,q=0不一定代表输入结束!(特别坑,在这个地方上耍我,出题人一定缺少关爱!)
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          0+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]+=maze[i][k]*rhs.maze[k][j];
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	ll p,q,k;
	while(scanf("%lld %lld",&p,&q)){
		if(!(~scanf("%lld",&k))){
			return 0;	
		}
		if(k==0){
			puts("2");
			continue;
		}
		matrix ans;
		ans.init(2);
		ans.maze[0][0]=2;ans.maze[0][1]=p;
		matrix ant;
		ant.init(2);
		ant.maze[1][0]=1;ant.maze[0][1]=-q;
		ant.maze[1][1]=p;
		ant=qlow(ant,k-1);
		ans=ans*ant;
		cout<<ans.maze[0][1]<<endl;
	}
    return 0;
}
但是呢,有个小问题,这个矩阵太大了,n可以到500,说不定会超时(我没写过,不知道是不是一定超时)。然后这里需要用到同构矩阵优化,用一维数组模拟二维矩阵乘法。(写这道题的时候,脑子特别不清醒,想了好久才把对应关系找到,汗)不知道的可以看我前面的矩阵专题!
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          500+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
//const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
ll m;
struct matrix{
	int n;
	ll maze[maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				ans.maze[i]=(ans.maze[i]+maze[(i+n-j)%n]*rhs.maze[j])%m;
		return ans;
	}
};
matrix qlow(matrix a,int n){
	matrix ans;
	ans.init(a.n);
	ans.maze[0]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
ll dat[maxn];
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int n,d,k;
	while(~scanf("%d %lld %d %d",&n,&m,&d,&k)){
		for(int i=0;i<n;i++)
			scanf("%lld",&dat[i]);
		matrix ans;
		ans.init(n);
		ans.maze[0]=1;
		for(int i=1;i<=d;i++)
			ans.maze[i]=ans.maze[n-i]=1;
		ans=qlow(ans,k);
		/*for(int i=0;i<n;i++)
			cout<<ans.maze[i]<<" ";
		cout<<endl;*/
		int cnt=0;
		for(int i=0;i<n;i++){
			if(cnt)putchar(' ');
			cnt=1;
			ll ant=0;
			for(int j=0;j<n;j++)
				ant=(ant+dat[j]*ans.maze[(j+n-i)%n])%m;
			printf("%lld",ant);
		}
		puts("");
	}
    return 0;
}
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          0+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
//const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
const ll mm = 987654321ll;
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%mm;
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	int p;
	while(scanf("%d",&p),p){
		if((p&1)||p<8){
			puts("0");
			continue;
		}
		matrix ans;
		ans.init(2);
		ans.maze[0][0]=ans.maze[1][0]=ans.maze[0][1]=1;
		ans=qlow(ans,p-4);
		printf("%lld\n",(ans.maze[0][0]-p/2+1+mm)%mm);
	}
    return 0;
}
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          80+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%mod;
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	ll n;
	int k;
	scanf("%I64d %d",&n,&k);
	if(n==1){
		puts("1");
		return 0;
	}
	matrix ans;
	ans.init(2*(k+1)+1);
	for(int i=0;i<k+1;i++)
		ans.maze[0][i]=1;
	for(int i=k+1;i<2*(k+1);i++)
		ans.maze[0][i]=(ans.maze[0][i-1]<<1)%mod;
	ans.maze[0][2*(k+1)]=ans.maze[0][2*(k+1)-1]+1;
	//for(int i=0;i<=2*(k+1);i++)
	//	cout<<ans.maze[0][i]<<endl;
	matrix ant;
	ant.init(2*(k+1)+1);
	for(int i=0;i<k+1;i++)
		ant.maze[i+k+1][i]=1;
	ant.maze[k+1][k+1]=1;
	for(int j=1;j<k+1;j++)
		for(int i=0;i<=j;i++)
			ant.maze[i+k+1][j+k+1]=(ant.maze[k+1+i][k+j]+ant.maze[i+k][j+k])%mod;
	for(int j=0;j<k+1;j++)
		for(int i=0;i<=j;i++)
			ant.maze[i][j+k+1]=ant.maze[i+k+1][j+k+1]*(1ll<<(j-i))%mod;
	for(int i=0;i<2*(k+1);i++)
		ant.maze[i][2*(k+1)]=ant.maze[i][2*(k+1)-1];
	ant.maze[2*(k+1)][2*(k+1)]=1;
	//for(int i=0;i<=2*(k+1);i++){
	//	for(int j=0;j<=2*(k+1);j++)
	//		cout<<ant.maze[i][j]<<" ";
	//	cout<<endl;
	//}
	ant=qlow(ant,n-2);
	ans=ans*ant;
	printf("%I64d\n",ans.maze[0][2*(k+1)]);
    return 0;
}
分析:这道就是题目难懂,解法上是一道常规的矩阵题。(题目意思太麻烦了,自己百度把)
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          0+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
ll x;
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator *(const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%x;
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	ll sx,sy,dx,dy,t;
	scanf("%I64d %I64d %I64d %I64d %I64d %I64d",&x,&sx,&sy,&dx,&dy,&t);
	matrix ans;
	ans.init(6);
	ans.maze[0][0]=ans.maze[0][1]=ans.maze[1][1]=1;
	ans.maze[1][2]=ans.maze[1][3]=ans.maze[1][4]=1;
	ans.maze[1][5]=ans.maze[2][4]=ans.maze[2][5]=ans.maze[2][3]=1;
	ans.maze[3][2]=ans.maze[3][4]=ans.maze[3][5]=1;
	ans.maze[4][2]=ans.maze[4][4]=ans.maze[5][3]=ans.maze[5][5]=1;
	ans.maze[0][2]=ans.maze[0][3]=ans.maze[0][4]=2;
	ans.maze[2][2]=ans.maze[3][3]=ans.maze[0][5]=2;
	ans=qlow(ans,t);
	matrix ant;
	ant.init(6);
	ant.maze[0][0]=1;ant.maze[0][2]=sx-1;ant.maze[0][3]=sy-1;
	ant.maze[0][4]=(dx%x+x)%x;ant.maze[0][5]=(dy%x+x)%x;
	ant=ant*ans;
	printf("%I64d %I64d\n",ant.maze[0][2]+1,ant.maze[0][3]+1);
    return 0;
}
我的代码Visual C++可以过,但是 GNU C++过不了,实在搞不清楚为什么,迷!
#include <map> #include <set> #include <ctime> #include <stack> #include <cmath> #include <queue> #include <bitset> #include <string> #include <vector> #include <cstdio> #include <cctype> #include <fstream> #include <cstdlib> #include <sstream> #include <cstring> #include <iostream> #include <algorithm> #pragma comment(linker, "/STACK:1024000000,1024000000") using namespace std; #define maxn 0+10 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define clr(x,y) memset(x,y,sizeof(x)) #define rep(i,n) for(int i=0;i<(n);i++) #define repf(i,a,b) for(int i=(a);i<=(b);i++) #define pii pair<int,int> #define mp make_pair #define FI first #define SE second #define IT iterator #define PB push_back #define Times 10 typedef long long ll; typedef unsigned long long ull; typedef long double ld; const double eps = 1e-10; const double pi = acos(-1.0); const ll mod = 1e9+7; const int inf = 0x3f3f3f3f; inline void RI(int& x) { x=0; char c=getchar(); while(!((c>='0'&&c<='9')||c=='-'))c=getchar(); bool flag=1; if(c=='-') { flag=0; c=getchar(); } while(c<='9'&&c>='0') { x=x*10+c-'0'; c=getchar(); } if(!flag)x=-x; } //-------------------------------------------------- ll m; struct matrix{ int n; ll maze[maxn][maxn]; void init(int n){ this->n=n; clr(maze,0); } matrix operator *(const matrix& rhs){ matrix ans; ans.init(n); for(int i=0;i<n;i++) for(int j=0;j<n;j++) for(int k=0;k<n;k++) ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%m; return ans; } }; matrix qlow(matrix a,ll n){ matrix ans; ans.init(a.n); for(int i=0;i<a.n;i++)ans.maze[i][i]=1; while(n){ if(n&1)ans=ans*a; a=a*a; n>>=1; } return ans; } int main(){ //freopen("d:\\acm\\in.in","r",stdin); int t; scanf("%d",&t); for(int cas=1;cas<=t;cas++){ ll n; int anw; scanf("%lld %lld",&n,&m); matrix ans; ans.init(3); ans.maze[0][0]=ans.maze[0][1]=1; ans.maze[0][2]=2; matrix ant; ant.init(3); ant.maze[0][1]=ant.maze[0][2]=ant.maze[1][0]=1; ant.maze[1][1]=ant.maze[1][2]=ant.maze[2][2]=1; ant=qlow(ant,n-2); ans=ans*ant; anw=ans.maze[0][2]; printf("Case %d: ",cas); if(anw==0||anw%2){ puts("No"); } else { puts("Yes"); int cnt=0; for(int i=0;i<anw;i++){ if(cnt)putchar(' '); cnt=1; putchar('1'); } puts(""); cnt=0; for(int i=0;i<anw;i++){ if(cnt)putchar(' '); cnt=1; if(i==0)putchar('0'); else printf("-1"); } puts(""); for(int i=0;i<anw-2;i++){ cnt=0; if(i<(anw-2)/2){ for(int j=0;j<anw;j++){ if(cnt)putchar(' '); cnt=1; if(j<i+2)putchar('1'); else printf("-1"); } } else { for(int j=0;j<anw;j++){ if(cnt)putchar(' '); cnt=1; if(j<i+1)putchar('1'); else if(j==i+1)putchar('0'); else printf("-1"); } } puts(""); } } } return 0; }
第十五题 UVA 10518
分析:题目首先得看懂,不懂的自己百度把。其实就是求一个类斐波那契数列,F(1)=1,F(2)=1,F(i)=F(i-1)+F(i-2)+1,i>=3
#include <map>
#include <set>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <bitset>
#include <string>
#include <vector>
#include <cstdio>
#include <cctype>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <cstring>
#include <iostream>
#include <algorithm>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define   maxn          10+10
#define   lson          l,m,rt<<1
#define   rson          m+1,r,rt<<1|1
#define   clr(x,y)      memset(x,y,sizeof(x))
#define   rep(i,n)      for(int i=0;i<(n);i++)
#define   repf(i,a,b)   for(int i=(a);i<=(b);i++)
#define   pii           pair<int,int>
#define   mp            make_pair
#define   FI            first
#define   SE            second
#define   IT            iterator
#define   PB            push_back
#define   Times         10
typedef   long long     ll;
typedef   unsigned long long ull;
typedef   long double   ld;
const double eps = 1e-10;
const double  pi = acos(-1.0);
const  ll    mod = 1e9+7;
const  int   inf = 0x3f3f3f3f;
inline void RI(int& x)
{
    x=0;
    char c=getchar();
    while(!((c>='0'&&c<='9')||c=='-'))c=getchar();
    bool flag=1;
    if(c=='-')
    {
        flag=0;
        c=getchar();
    }
    while(c<='9'&&c>='0')
    {
        x=x*10+c-'0';
        c=getchar();
    }
    if(!flag)x=-x;
}
//--------------------------------------------------
ll b;
struct matrix{
	int n;
	ll maze[maxn][maxn];
	void init(int n){
		this->n=n;
		clr(maze,0);
	}
	matrix operator * (const matrix& rhs){
		matrix ans;
		ans.init(n);
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				for(int k=0;k<n;k++)
					ans.maze[i][j]=(ans.maze[i][j]+maze[i][k]*rhs.maze[k][j])%b;
		return ans;
	}
};
matrix qlow(matrix a,ll n){
	matrix ans;
	ans.init(a.n);
	for(int i=0;i<a.n;i++)ans.maze[i][i]=1;
	while(n){
		if(n&1)ans=ans*a;
		a=a*a;
		n>>=1;
	}
	return ans;
}
int main(){
	//freopen("d:\\acm\\in.in","r",stdin);
	ll n;
	int cas=1;
	while(scanf("%lld %lld",&n,&b),n||b){
		matrix ans;
		ans.init(3);
		ans.maze[0][0]=ans.maze[0][2]=1;
		ans.maze[1][2]=ans.maze[2][1]=ans.maze[2][2]=1;
		printf("Case %d: %lld %lld",cas++,n,b);
		if(n==0){
			printf(" %d\n",1%b);
			continue;
		}
		matrix ant;
		ant.init(3);
		ant.maze[0][0]=ant.maze[0][1]=ant.maze[0][2]=1;
		ans=qlow(ans,n-1);
		ant=ant*ans;
		printf(" %lld\n",ant.maze[0][2]);
	}
    return 0;
}
小结: 总算完成了kuangbin先生的矩阵专题了,已经不记得这是我做完的kuangbin先生的第几个专题了!累!但是满满的充实感!
原文:http://blog.csdn.net/shengtao96/article/details/51849216