矩阵连乘
本以为很开心的一道题,矩阵构造太难写了。。
0. 1. 2. 2. 3. 3. 4. 4. 4. 4. 5. 6.
ab ab ab aa ab ab ab ab aa ac aa aa
cd ba ab bb ca bc ac cb cb bb aa ab这是我人肉的7中情况。。。然后。。。额。。。写了一下午。。。
叉姐好神啊!他貌似先求了4的最小表示,在求了8的最小表示然后。。。
我大概人肉了这7种情况的最小表示,然后枚举了剩下4个的最小表示?反正写的它麻麻都不认识他了。。。
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
class TheBrickTowerHardDivOne {
public:
int find(int, int, long long);
};
/*
0. 1. 2. 2. 3. 3. 4. 4. 4. 4. 5. 6.
ab ab ab aa ab ab ab ab aa ac aa aa
cd ba ab bb ca bc ac cb cb bb aa ab
0->0
*/
int f[7][4] = { { 0, 1, 2, 3 }, { 0, 1, 1, 0 }, { 0, 1, 0, 1 }, { 0, 1, 2, 0 },
{ 0, 1, 0, 2 }, { 0, 0, 0, 0 }, { 0, 0, 0, 1 } };
int id[7][8];
long long a[66][66], t[66][66], tmp[66][66];
int b[4];
bool flag[10];
int ed;
long long pmod = 1234567891;
void mul(long long a[][66], long long b[][66]) {
int i, j, k;
memset(tmp, 0, sizeof(tmp));
for (i = 0; i < ed; ++i) {
for (j = 0; j < ed; ++j) {
for (k = 0; k < ed; ++k) {
tmp[i][j] += a[i][k] * b[k][j] % pmod;
tmp[i][j] %= pmod;
}
}
}
for (i = 0; i < ed; ++i) {
for (j = 0; j < ed; ++j)
a[i][j] = tmp[i][j];
}
}
int TheBrickTowerHardDivOne::find(int C, int K, long long H) {
int i, j, k, p;
ed = 0;
for (i = 0; i < 7; ++i) {
for (j = 0; j <= K; ++j) {
id[i][j] = ed;
ed++;
}
}
memset(a, 0, sizeof(a));
for (i = 0; i < 7; ++i) {
for (b[0] = 0; b[0] < 8; ++b[0]) {
for (b[1] = 0; b[1] < 8; ++b[1]) {
for (b[2] = 0; b[2] < 8; ++b[2]) {
for (b[3] = 0; b[3] < 8; ++b[3]) {
if (f[i][0] >= C)
continue;
if (f[i][1] >= C)
continue;
if (f[i][2] >= C)
continue;
if (f[i][3] >= C)
continue;
if (b[0] >= C)
continue;
if (b[1] >= C)
continue;
if (b[2] >= C)
continue;
if (b[3] >= C)
continue;
memset(flag, false, sizeof(flag));
long long v = 1;
flag[f[i][0]] = true;
flag[f[i][1]] = true;
flag[f[i][2]] = true;
flag[f[i][3]] = true;
if (!flag[b[0]])
v *= max(0, C - b[0]);
v %= pmod;
for (p = 0; p < b[0]; ++p) {
if (!flag[p])
break;
}
if (p < b[0])
continue;
flag[b[0]] = true;
if (!flag[b[1]])
v *= max(0, C - b[1]);
v %= pmod;
for (p = 0; p < b[1]; ++p) {
if (!flag[p])
break;
}
if (p < b[1])
continue;
flag[b[1]] = true;
if (!flag[b[2]])
v *= max(0, C - b[2]);
v %= pmod;
for (p = 0; p < b[2]; ++p) {
if (!flag[p])
break;
}
if (p < b[2])
continue;
flag[b[2]] = true;
if (!flag[b[3]])
v *= max(0, C - b[3]);
v %= pmod;
for (p = 0; p < b[3]; ++p) {
if (!flag[p])
break;
}
if (p < b[3])
continue;
flag[b[3]] = true;
int add = 0;
if (b[0] == f[i][0])
add++;
if (b[1] == f[i][1])
add++;
if (b[2] == f[i][2])
add++;
if (b[3] == f[i][3])
add++;
if (b[0] == b[1])
add++;
if (b[1] == b[3])
add++;
if (b[3] == b[2])
add++;
if (b[2] == b[0])
add++;
int typ;
if (b[0] == b[1] && b[1] == b[2] && b[2] == b[3])
typ = 5;
else if (b[0] == b[1] && b[1] == b[3])
typ = 6;
else if (b[1] == b[3] && b[3] == b[2])
typ = 6;
else if (b[3] == b[2] && b[2] == b[0])
typ = 6;
else if (b[2] == b[0] && b[0] == b[1])
typ = 6;
else if (b[0] == b[1] && b[2] == b[3])
typ = 2;
else if (b[0] == b[2] && b[1] == b[3])
typ = 2;
else if (b[0] == b[3] && b[1] == b[2])
typ = 1;
else if (b[0] == b[1] || b[1] == b[3] || b[3] == b[2]
|| b[2] == b[0])
typ = 4;
else if (b[0] == b[3] || b[1] == b[2])
typ = 3;
else
typ = 0;
for (k = 0; k + add <= K; ++k) {
a[id[i][k]][id[typ][k + add]] += v;
a[id[i][k]][id[typ][k + add]] %= pmod;
}
}
}
}
}
}
memset(t, 0, sizeof(t));
for (i = 0; i < ed; ++i) {
a[i][ed] = 1;
t[i][i] = 1;
}
t[ed][ed] = 1;
a[ed][ed] = 1;
ed++;
while (H) {
if (H & 1)
mul(t, a);
mul(a, a);
H >>= 1;
}
long long ans = 0;
/*
0. 1. 2. 2. 3. 3. 4. 4. 4. 4. 5. 6.
ab ab ab aa ab ab ab ab aa ac aa aa
cd ba ab bb ca bc ac cb cb bb aa ab
*/
//0
if (C >= 4)
ans += t[id[0][0]][ed - 1] * C * (C - 1) % pmod * (C - 2) * (C - 3)
% pmod;
//1
if (C >= 2)
ans += t[id[1][0]][ed - 1] * C * (C - 1) % pmod;
//2
if (C >= 2)
if (K >= 2)
ans += t[id[2][2]][ed - 1] * C * (C - 1) * 2 % pmod;
//3
if (C >= 3)
ans += t[id[3][0]][ed - 1] * C * (C - 1) % pmod * (C - 2) * 2 % pmod;
//4
if (C >= 3)
if (K >= 1)
ans += t[id[4][1]][ed - 1] * C * (C - 1) % pmod * (C - 2) * 4
% pmod;
//5
if (C >= 1)
if (K >= 4)
ans += t[id[5][4]][ed - 1] * C;
//6
if (C >= 2)
if (K >= 2)
ans += t[id[6][2]][ed - 1] * C * (C - 1) * 4 % pmod;
ans %= pmod;
return ans;
}
432

被折叠的 条评论
为什么被折叠?



