先找规律:
1:1 0000
2:5 0000 0011 1111 1001 11000000 0011 1111 1001 1100
3:11 0000 0000 0000 0000 1100 1111 0011 0011 1100 1001 0000
0000 0011 1100 1111 1100 1111 0011 1111 1111 1001 1001
0000 0011 1100 1111 0000 0000 0000 1100 0011 0000 1001
4:。。。
5:。。。
状态方式倒过来递推思考:
当f[n-1]满时只有一种情况0000
当f[n-2]满时有4种情况
0011 1100 1001 1111
0011 1100 1001 1111
当f[n-3]满时只有2种情况
0011 1100
1111 1111
1100 0011
当f[n-4]满时只有3种情况
0011 1100 1001
1111 1111 1111
1111 1111 1111
0011 1100 1001
当f[n-5]满时只有2种情况
0011 1100
1111 1111
1111 1111
1111 1111
1100 0011
规律:
f[n]=f[n-1]+4f[n-2]+2(f[n-3]+f[n-5]+....f[0])+3(f[n-4]+f[n-6]+..f[0])f[1]=f[0]=1
f[2]=f[1]+4f[0]=5
f[3]=f[2]+4f[1]+2f[0]=5+4+2=11
f[4]=f[3]+4f[2]+2f[1]+3f[0]=11+20+2+3=36
f[5]=f[4]+4f[3]+2f[2]+3f[1]+2f[0]=36+44+10+3+2=95
....
最终公式:
f[n]=f[n-1]+5f[n-2]+f[n-3]-f[n-4]
矩阵构造:
由于N高达10^9,所以要用矩阵进行优化。|0 1 0 0|
|0 0 1 0|
|0 0 0 1|
|-1 1 5 1|
与
|a[i-3]|
|a[i-2]|
|a[i-1]|
|a[i]|
#include
using namespace std;
#include
#include
const int MAXN=10;
int n;
int mod;
class Matrix{
public:
int n;//行
int m;//列
int a[MAXN][MAXN];
void clear(){
n=m=0;
memset(a,0,sizeof(a));
}
Matrix operator +(const Matrix &b)const{
Matrix tmp;
tmp.n=n;
tmp.m=m;
for(int i=0;i
>=1;
}
return ret.a[0][0];
}
/*
n=1:rul 5 11 36..
n=2:rul*rul 11
n=3:rul*rul*rul 36
*/
int main()
{
while(scanf("%d%d",&n,&mod),n||mod){
if(n==1)
printf("%d\n",1%mod);
else
printf("%d\n",quickPow_Matrix(n-1));
}
}