luogu Eat the Trees
阿新 • • 發佈:2019-03-12
ini long 限制 方法 amp etc con ans sizeof
/* 用和模板類似的方法就行 但是實際上弱化版不用考慮匹配情況限制更加寬松, 只需要保存每個位置有無插頭即可, */ #include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<queue> #include<cmath> #define ll long long #define M 13 #define mmp make_pair using namespace std; int read() { int nm = 0, f = 1; char c = getchar(); for(; !isdigit(c); c = getchar()) if(c == '-') f = -1; for(; isdigit(c); c = getchar()) nm = nm * 10 + c - '0'; return nm * f; } const int hs = 299987; int mp[M][M], ex, ey, now, last, bit[30], g[2][300010], tot[2], n, m; ll ans, f[2][300010]; struct Note { int nxt, to; } note[300010]; int head[300010], cnt = 0; void insert(int x, ll v) { int key = x % hs; for(int i = head[key]; i; i = note[i].nxt) { if(g[now][note[i].to] == x) { f[now][note[i].to] += v; return; } } tot[now]++; g[now][tot[now]] = x; f[now][tot[now]] = v; note[++cnt].nxt = head[key]; head[key] = cnt; note[cnt].to = tot[now]; } void Dp() { now = 1, last = 0; tot[now] = 1; f[now][1] = 1; g[now][1] = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= tot[now]; j++) g[now][j] <<= 1; for(int j = 1; j <= m; j++) { cnt = 0; memset(head, 0, sizeof(head)); swap(now, last); tot[now] = 0; ll nowans; int nowsta, sd, sr; for(int k = 1; k <= tot[last]; k++) { nowsta = g[last][k], nowans = f[last][k]; sd = (nowsta >> bit[j]) % 2, sr = (nowsta >> bit[j - 1]) % 2; if(!mp[i][j]) { if(!sd && !sr) insert(nowsta, nowans); } else if(!sd && !sr) { if(mp[i + 1][j] && mp[i][j + 1]) insert(nowsta + (1 << bit[j - 1]) + (1 << bit[j]), nowans); } else if(!sd && sr) { if(mp[i + 1][j]) insert(nowsta, nowans); if(mp[i][j + 1]) insert(nowsta - (1 << bit[j - 1]) + (1 << bit[j]), nowans); } else if(sd && !sr) { if(mp[i + 1][j]) insert(nowsta - (1 << bit[j]) + (1 << bit[j - 1]), nowans); if(mp[i][j + 1]) insert(nowsta, nowans); } else { insert(nowsta - (1 << bit[j]) - (1 << bit[j - 1]), nowans); if(i == ex && j == ey) ans += nowans; } } } } } void init() { ans = 0; ex = 0, ey = 0; memset(f, 0, sizeof(f)); memset(g, 0, sizeof(g)); memset(mp, 0, sizeof(mp)); } int main() { int T = read(); for(int i = 1; i <= 25; i++) bit[i] = i; while(T--) { init(); n = read(), m = read(); for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { int x = read(); if(x == 1) mp[i][j] = 1, ex = i, ey = j; } } Dp(); if(ex == 0 && ey == 0) ans++; cout << ans << '\n'; } return 0; } /* 2 2 4 1 1 1 1 1 1 1 1 6 3 1 1 1 1 0 1 1 1 1 1 1 1 1 0 1 1 1 1 1 3 3 0 0 0 0 0 0 0 0 0 */
luogu Eat the Trees