4*N的地板上用2*1的瓷砖铺满,求所有方案数对M求余。
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.PrintWriter; import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { new POJ3420().run(); } } class POJ3420 { void run() { Scanner cin = new Scanner(new BufferedInputStream(System.in)); PrintWriter cout = new PrintWriter(new BufferedOutputStream(System.out)); long[][] val = new long[16][16]; dfs(0, 0, 0, val, 4); int n; while (true) { n = cin.nextInt(); Mat.mod = cin.nextLong(); if (n == 0 && Mat.mod == 0) break; Mat mat = new Mat(val); mat = mat.pow(n); cout.println(mat.val[15][15]); } cout.flush(); } void dfs(int pos, int from, int to, long[][] val, int w) { if (pos > w) return; if (pos == w) { val[from][to]++; return; } dfs(pos + 2, from << 2 | 3, to << 2 | 3, val, w); dfs(pos + 1, from << 1 | 1, to << 1, val, w); dfs(pos + 1, from << 1, to << 1 | 1, val, w); } final int N = 11; long[][] dp = new long[N + 1][(1 << N) + 1]; } class Mat { static long mod; long[][] val = new long[16][16]; Mat(long[][] val) { for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { this.val[i][j] = val[i][j]; } } } Mat() { } Mat One() { Mat res = new Mat(); for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { res.val[i][j] = i == j ? 1L : 0L; } } return res; } Mat Zero() { Mat res = new Mat(); for (int i = 0; i <= 15; i++) { Arrays.fill(res.val[i], 0); } return res; } Mat mult(Mat other) { Mat res = Zero(); for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) { for (int k = 0; k <= 15; k++) { res.val[i][j] += this.val[i][k] * other.val[k][j] % mod; res.val[i][j] %= mod; } } } return res; } Mat pow(int y) { Mat res = One(); Mat x = this; for (; y > 0; y >>= 1) { if ((y & 1) > 0) { res = res.mult(x); } x = x.mult(x); } return res; } @Override public String toString() { // TODO Auto-generated method stub String s = ""; for (int i = 0; i <= 15; i++) { for (int j = 0; j <= 15; j++) s += val[i][j] + " "; s += "\n"; } return s; } }