如果你矩乘 TLE
查看原帖
如果你矩乘 TLE
759459
flowing_boat楼主2024/5/29 23:28
  • 检查你的标记矩阵大小是否 ≤5×5\le 5 \times 5,如果不是,请尝试缩小您的矩阵。

  • Step 1:循环展开,建议只展开一层,效果就很显著了。

REP(i, 0, a.x)
  REP(j, 0, b.y)
     c.v[i][j] = a.v[i][0] * b.v[0][j] + a.v[i][1] * b.v[1][j] + a.v[i][2] * b.v[2][j] + a.v[i][3] * b.v[3][j] + a.v[i][4] * b.v[4][j];
  • Step 2:不要用构造函数清空,尝试利用之前矩阵的信息,尽量少修改元素。(可以认为每次只修改当前矩阵和目标矩阵有区别的地方,不要挨个挨个清空和修改)

  • Step 3:pushdown 判断是否为单位矩阵和清空时,循环展开:

if (a.v[0][1] || a.v[0][2] || a.v[0][3] || a.v[0][4]) return false;
if (a.v[1][0] || a.v[1][2] || a.v[1][3] || a.v[1][4]) return false;
if (a.v[2][0] || a.v[2][1] || a.v[2][3] || a.v[2][4]) return false;
if (a.v[3][0] || a.v[3][1] || a.v[3][2] || a.v[3][4]) return false;
if (a.v[4][0] || a.v[4][1] || a.v[4][2] || a.v[4][3]) return false;
if (a.v[0][0] != 1 || a.v[1][1] != 1 || a.v[2][2] != 1 || a.v[3][3] != 1 || a.v[4][4] != 1) return false;

tg[x].v[0][1] = tg[x].v[0][2] = tg[x].v[0][3] = tg[x].v[0][4] = 0;
tg[x].v[1][0] = tg[x].v[1][2] = tg[x].v[1][3] = tg[x].v[1][4] = 0;
tg[x].v[2][0] = tg[x].v[2][1] = tg[x].v[2][3] = tg[x].v[2][4] = 0;
tg[x].v[3][0] = tg[x].v[3][1] = tg[x].v[3][2] = tg[x].v[3][4] = 0;
tg[x].v[4][0] = tg[x].v[4][1] = tg[x].v[4][2] = tg[x].v[4][3] = 0;
tg[x].v[0][0] = tg[x].v[1][1] = tg[x].v[2][2] = tg[x].v[3][3] = tg[x].v[4][4] = 1;
  • Step 4:尝试把你存值的矩阵开成 1×51 \times 5,在重载加法时可以发现加法只会是两个 1×51 \times 5 的矩阵相加,直接砍掉 5×55 \times 5 的枚举,当然要循环展开。
c.v[0][0] = a.v[0][0] + b.v[0][0], c.v[1][0] = a.v[1][0] + b.v[1][0], c.v[2][0] = a.v[2][0] + b.v[2][0], c.v[3][0] = a.v[3][0] + b.v[3][0], c.v[4][0] = a.v[4][0] + b.v[4][0];  
  • Step 5:读入读出优化。

  • Step 6:如果你还过不了,尝试精细化处理,矩阵只开一维,维护所有有意义的值,常数会更小。

2024/5/29 23:28
加载中...