【YBTOJ】涂抹果酱
涂抹果酱
题目大意:
在一个 \(n\times m\) 的矩阵上可以染三个色,同色不相邻。已给出第 \(k\) 行的方案,求方案数。
正文:
三进制状压,求出来用 \(k-1\) 的方案乘上 \(n-k\) 的方案即可。
代码:
const int N = 1e4 + 10, M = 10, M2 = 105;
const int mod = 1e6;
inline ll Read()
{
ll x = 0, f = 1;
char c = getchar();
while (c != '-' && (c < '0' || c > '9')) c = getchar();
if (c == '-') f = -f, c = getchar();
while (c >= '0' && c <= '9') x = (x << 3) + (x << 1) + c - '0', c = getchar();
return x * f;
}
ll n, m, k;
ll a, p[M] = {1, 3, 9, 27, 81, 243, 729};
ll st[M2];
bool And(int A, int B, bool op = 0)
{
int i;
for (i = op; A || B; i++, A /= 3, B /= 3)
if (A % 3 == B % 3) return 1;
if (i < m) return 1;
return 0;
}
void Prework()
{
for (int i = 0; i < p[m]; i++)
{
if(And(i, i / 3, 1)) continue;
st[++st[0]] = i;
}
}
ll f[N][M2];
void calc()
{
for (int i = 1; i <= st[0]; i++)
if (!And(st[i], a))
f[1][i] = 1;
for (int i = 2; i <= n; i++)
{
for (int j = 1; j <= st[0]; j++)
for (int k = 1; k <= st[0]; k++)
if(!And(st[j], st[k]))
(f[i][j] += f[i - 1][k]) %= mod;
}
}
ll Solve(int n)
{
if (n == 0) return 1;
int ans = 0;
for (int i = 1; i <= st[0]; i++)
(ans += f[n][i]) %= mod;
return ans;
}
int main()
{
n = Read(), m = Read(), k = Read();
for (int i = 1; i <= m; i++)
{
a = a * 3 + Read() % 3;
if (a % 3 == a / 3 % 3 && i != 1) {puts("0"); return 0;}
}
Prework();
calc();
printf ("%lld\n", 1ll * Solve(k - 1) * Solve(n - k) % mod);
return 0;
}