【矩阵快速幂】 HDOJ 5434 Peace small elephant

对每一列状态压缩,然后矩阵加速即可。。。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

const int mod = 1e9+7;
const int maxn = 130;

LL mat[maxn][maxn];
LL mid[maxn][maxn];
LL res[maxn][maxn];
int n, m;

void calc(int b)
{
	int N = 1 << m;
	memset(res, 0, sizeof res);
	for(int i = 0; i < N; i++) res[i][i] = 1;
	while(b) {
		if(b % 2) {
			for(int i = 0; i < N; i++)
				for(int j = 0; j < N; j++) {
					LL t = 0;
					for(int k = 0; k < N; k++)
						t = (t + res[i][k] * mat[k][j]) % mod;
					mid[i][j] = t;
				}
			memcpy(res, mid, sizeof res);
		}
		for(int i = 0; i < N; i++)
			for(int j = 0; j < N; j++) {
				LL t = 0;
				for(int k = 0; k < N; k++)
					t = (t + mat[i][k] * mat[k][j]) % mod;
				mid[i][j] = t;
			}
		memcpy(mat, mid, sizeof mat);
		b /= 2;
	}
}

bool check(int a, int b)
{
	for(int i = 0; i < m; i++) {
		if((1 << i) & b) {
			if(i) {
				if(((1 << i-1) & a) && ((1 << i-1) & b) == 0 && ((1 << i) & a) == 0)
					return 0;
			}
			if(i+1 < m) {
				if(((1 << i+1) & a) && ((1 << i+1) & b) == 0 && ((1 << i) & a) == 0)
					return 0;
			}
		}
	}
	return 1;
}

void work()
{
	memset(mat, 0, sizeof mat);
	for(int i = 0; i < 1 << m; i++)
		for(int j = 0; j < 1 << m; j++)
			mat[i][j] = check(i, j);
	calc(n);
	LL ans = 0;
	for(int i = 0; i < 1 << m; i++) ans = (ans + res[0][i]) % mod;
	printf("%lld\n", ans);
}

int main()
{
	while(scanf("%d%d", &n, &m) != EOF) {
		work();
	}
	
	return 0;
}


你可能感兴趣的:(矩阵快速幂)