【插头DP】 ZOJ 3256 Tour in the Castle
通道:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3256
题意:简单路径-左上角走到左下角的路径方案数。
思路:M太大,需快速幂,预处理所有状态即可。
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 5 using namespace std; 6 7 const int maxn = 10001; 8 const int MOD = 7777777; 9 const int mov[10]={0,2,4,6,8,10,12,14,16}; 10 11 int n, m; 12 int mp[2 << 16], res[130], tem[130], pos; 13 bool vd[2 << 16]; 14 int A[6][30][130][130], B[130][130], len[6], sp[6][2]; 15 16 struct node { 17 int size, head[maxn], next[maxn], sta[maxn]; 18 inline void clear() { 19 memset(head, -1, sizeof head); 20 size = 0; 21 } 22 inline void push(int st) { 23 int hash = st % maxn; 24 for (int i = head[hash]; ~i; i = next[i]) if (sta[i] == st) 25 return ; 26 sta[size] = st; next[size] = hash; 27 head[hash] = size++; 28 } 29 }dp[2]; 30 31 inline int getbit(int st, int k){return 3 & (st >> mov[k]); } 32 inline int pybit(int st, int k){return st << mov[k]; } 33 inline int clrbit(int st, int a, int b){return st & (~(3 << mov[a])) & (~(3 << mov[b])); } 34 35 inline int fl(int st, int k, int n) { 36 int cnt = 1; 37 for(int i = k + 1; i <= n; ++i) { 38 int e = getbit(st, i); 39 if(e == 2) cnt--; 40 else if(e == 1) cnt++; 41 if(cnt == 0) return i; 42 } 43 } 44 45 inline int fr(int st, int k) { 46 int cnt = 1; 47 for(int i = k - 1; i >= 0; --i) { 48 int e = getbit(st, i); 49 if(e == 2) cnt++; 50 else if(e == 1) cnt--; 51 if(cnt == 0) return i; 52 } 53 } 54 55 inline int find(int st) { 56 if(mp[st] == -1) mp[st] = pos++; 57 return mp[st]; 58 } 59 60 void bfs(int n) { 61 queue<int > q; 62 memset(vd, 0, sizeof vd); 63 memset(mp, -1, sizeof mp); 64 memset(B, 0, sizeof B); 65 pos = 0; 66 int in = pybit(1, 0) + pybit(2, n - 1); 67 vd[in] = 1; 68 q.push(in); 69 while(!q.empty()) { 70 int out = q.front(); q.pop(); 71 dp[0].clear(); 72 dp[0].push(out << 2); 73 int now = 0, pre = 1; 74 for(int j = 1; j <= n; ++j) { 75 pre = now, now ^= 1; dp[now].clear(); 76 for (int k = 0; k < dp[pre].size; ++k) { 77 int l = getbit(dp[pre].sta[k], j - 1); 78 int up = getbit(dp[pre].sta[k], j); 79 int st = clrbit(dp[pre].sta[k], j - 1, j); 80 if(!l && !up) { 81 if(j < n) dp[now].push(st | pybit(1,j-1) | pybit(2,j)); 82 } else if(!l || !up) { 83 int e = l == 0 ? up : l; 84 dp[now].push(st | pybit(e, j - 1)); 85 if(j < n) dp[now].push(st | pybit(e, j)); 86 } else if(l == 1 && up == 1) dp[now].push(st ^ pybit(3, fl(st, j, n))); 87 else if(l == 2 && up == 2) dp[now].push(st ^ pybit(3, fr(st, j - 1))); 88 else if(l == 2 && up == 1) dp[now].push(st); 89 else if(j == n && st == 0) ++B[find(out)][find(st)]; 90 } 91 } 92 for(int j = 0; j < dp[now].size; ++j) { 93 in = dp[now].sta[j]; 94 if(!vd[in]) { 95 vd[in] = 1; 96 q.push(in); 97 } 98 ++B[find(out)][find(in)]; 99 } 100 } 101 } 102 103 void init() { 104 for (int i = 0; i <= 5; ++i) { 105 bfs(i + 2); 106 len[i] = pos; 107 sp[i][0] = find(pybit(1, 0) + pybit(2, i + 1)); 108 sp[i][1] = find(0); 109 for (int j = 0; j < len[i]; ++j) 110 for (int k = 0; k < len[i]; ++k) 111 A[i][0][j][k] = B[j][k]; 112 for (int j = 1; j < 30; ++j) { 113 for (int x = 0; x < len[i]; ++x) { 114 for (int y = 0; y < len[i]; ++y) { 115 for (int z = 0; z < len[i]; ++z) { 116 long long t = (long long)(A[i][j - 1][x][z] * (long long)A[i][j - 1][z][y]); 117 if(t >= MOD) t %= MOD; 118 A[i][j][x][y] += t; 119 if(A[i][j][x][y] >= MOD) A[i][j][x][y] -= MOD; 120 } 121 } 122 } 123 } 124 } 125 } 126 127 void Exp(int k, int e) { 128 int cnt = 0; 129 while(k > 0) { 130 if (k & 1) { 131 for (int j = 0; j < len[e]; ++j) { 132 tem[j] = 0; 133 for (int k = 0; k < len[e]; ++k) { 134 long long t = (long long) res[k] * (long long)A[e][cnt][k][j]; 135 if (t >= MOD) t %= MOD; 136 tem[j] += t; 137 if (tem[j] >= MOD) tem[j] -= MOD; 138 } 139 } 140 memcpy(res, tem, sizeof tem); 141 } 142 k >>= 1; ++cnt; 143 } 144 } 145 146 int main() { 147 init(); 148 while (2 == scanf("%d%d", &n, &m)) { 149 memset(res, 0, sizeof res); 150 res[sp[n - 2][0]] = 1; 151 Exp(m, n - 2); 152 if (res[sp[n - 2][1]] == 0) puts("Impossible"); 153 else printf("%d\n", res[sp[n - 2][1]]); 154 } 155 return 0; 156 }