2016 Multi-University Training Contest 1 I. Solid Dominoes Tilings
2016-08-28 20:23
225 查看
Solid Dominoes Tilings
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 235 Accepted Submission(s): 143
[align=left]Problem Description[/align]
Dominoes are rectangular tiles with nice 2 × 1 and 1 × 2 sizes.
The tiling is called solid if it is not possible to split the tiled rectangle by a straight line, not crossing the interior of any tile. For example, on the picture below the tilings (a) and (b) are solid, while the tilings (c) and (d) are not.
const int N = 18, M = 2000010, MOD = 1e9 + 7; int head[1 << N], son[M], nex[M], tot; int ans , blocks ; int width; int G [1 << N], g ; inline int add(int x, int y) { return ((x + y) % MOD + MOD) % MOD; } inline int mul(int x, int y) { return ((x * 1ll * y) % MOD + MOD) % MOD; } inline void addEdge(int u, int v) { son[tot] = v, nex[tot] = head[u]; head[u] = tot++; } inline void searchNexState(int goalState, int nowState, int d) { if(d == width) addEdge(goalState, nowState); else if((goalState >> d) & 1) { if(d < width - 1 && (goalState >> (d + 1) & 1)) { int nexState = nowState; nexState |= (1 << d) | (1 << (d + 1)); searchNexState(goalState, nexState, d + 2); } searchNexState(goalState, nowState, d + 1); } else searchNexState(goalState, nowState | (1 << d), d + 1); } inline void getTransfer(int n) { width = n, tot = 0; for(int i = 0; i < (1 << n); ++i) { head[i] = -1; searchNexState(i, 0, 0); } // printf("%d\n", tot); } inline void getG(int n, int m) { for(int tab = head[(1 << m) - 1]; tab != -1; tab = nex[tab]) G[1][son[tab]] = 1; for(int i = 1; i < n; ++i) { for(int u = 0; u < (1 << m); ++u) G[i + 1][u] = 0; for(int u = 0; u < (1 << m); ++u) { if(G[i][u]) { for(int tab = head[u]; tab != -1; tab = nex[tab]) G[i + 1][son[tab]] = add(G[i + 1][son[tab]], G[i][u]); } } } for(int i = 1; i <= n; ++i) g[i][m] = G[i][(1 << m) - 1]; } inline void search(int w, int now, int len) { if(w >= width) { blocks[len++] = now; static int F , G ; for(int n = 1; n <= 16; ++n) { int cnt = 1; for(int i = 0; i < len; ++i) cnt = mul(cnt, g [blocks[i]]); F = G = cnt; for(int h = 1; h < n; ++h) F = add(F , -mul(F[h], G[n - h])); if(len & 1) ans [width] = add(ans [width], F ); else ans [width] = add(ans [width], -F ); } } else { search(w + 1, now + 1, len); blocks[len] = now; search(w + 1, 1, len + 1); } } inline void init() { for(int m = 1; m <= 16; ++m) { width = m; getTransfer(m); getG(16, m); search(1, 1, 0); } } int n, m; int main() { init(); while(scanf("%d%d", &n, &m) == 2) printf("%d\n", ans [m]); return 0; }
View Code
相关文章推荐
- 【HDU5731 2016 Multi-University Training Contest 1I】【轮廓线DP+容斥】Solid Dominoes Tilings nm棋盘1x2多边形填充稳定方案
- 2016 Multi-University Training Contest 1 1002 Chess
- 2016 Multi-University Training Contest 1-1001---HDU 5723 Abandoned country(DFS+最小生成树)
- 2016 Multi-University Training Contest 1-1011---HDU 5733 tetrahedron(计算几何)
- 2016 Multi-University Training Contest 2 1005 hdu 5738 计算几何
- 2016 Multi-University Training Contest 2题解报告
- 2016 Multi-University Training Contest 2 Acperience
- 【HDU5726 2016 Multi-University Training Contest 1D】【gcd的下降性质 STL-map】GCD 多少段区间gcd等于给定区间gcd
- 2016 Multi-University Training Contest 2 总结
- [HDU5727] Necklace [2016 Multi-University Training Contest 1(2016多校联合训练1) E]
- HDU 5775 Bubble Sort(线段树)(2016 Multi-University Training Contest 4 1012)
- 2016 Multi-University Training Contest 4
- 2016 Multi-University Training Contest 4 1007 (hdu 5770)
- 2016 Multi-University Training Contest 4 1005Lucky7
- 2016 Multi-University Training Contest 6 题解
- hdu 5793 2016 Multi-University Training Contest 6(快速幂+乘法逆元)
- hdu 5802 2016 Multi-University Training Contest 6(dfs)
- 数据结构 ( 优先队列&&栈 )——HDU 5818 ( 2016 Multi-University Training Contest 7 1010 )
- hdu 5831 Rikka with Parenthesis II(2016 Multi-University Training Contest 8——模拟)
- 2016 Multi-University Training Contest 3 solutions BY 绍兴一中