链接:
题解:
直接讲构造FWT吧,其他都很简单不想说了。
这里是做
3
进制异或,考虑分治乘。
T1=A0B1+A1B0+A2B2
T2=A0B2+A1B1+A2B0
如果使用待定系数法,用
(A0+xA1+yA2)(B0+xB1+yB2)
来构造,那么发现需要满足三个条件:
xy=1,x2=y,y2=x
这提示我们三次单位根。记
w
表示三次单位根,有:
记
注意到
w2+w+1=0
,
那么
(1111ww21w2w)×(1111w2w1ww2)=3I
,其中
I
是单位矩阵。
还有一个问题是
这里只需要
3
在模
代码:
#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;
typedef long long LL;
typedef pair <int, int> pii;
inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}
const int MAXN = 15;
const int MAXM = 531445;
int n, m, t, mod, pwd[MAXN], cnx[MAXM], cny[MAXM], trans[MAXN][MAXN];
struct Number
{
int x, y;
Number(int _x = 0, int _y = 0) { x = _x, y = _y; }
Number operator + (const Number &b) const { return Number((x + b.x) % mod, (y + b.y) % mod); }
Number operator - (const Number &b) const { return Number((x - b.x + mod) % mod, (y - b.y + mod) % mod); }
Number operator * (const Number &b) const { return Number((1LL * x * b.x - 1LL * y * b.y % mod + mod) % mod, (1LL * x * b.y + 1LL * y * b.x - 1LL * y * b.y % mod + mod) % mod); }
} a[MAXM], b[MAXM];
Number Qow(Number x, int y)
{
Number r(1, 0);
for (; y; y >>= 1, x = x * x)
if (y & 1)
r = r * x;
return r;
}
inline void Exgcd(int a, int b, int &x, int &y)
{
if (!b)
x = 1, y = 0;
else
Exgcd(b, a % b, y, x), y -= a / b * x;
}
inline void DFT(Number *a)
{
Number b[3];
b[0] = a[0] + a[1] + a[2];
b[1] = Number((1LL * a[0].x - a[1].y - a[2].x + a[2].y + (mod << 1)) % mod, (1LL * a[0].y + a[1].x - a[1].y - a[2].x + (mod << 1)) % mod);
b[2] = Number((1LL * a[0].x - a[1].x + a[1].y - a[2].y + (mod << 1)) % mod, (1LL * a[0].y - a[1].x + a[2].x - a[2].y + (mod << 1)) % mod);
a[0] = b[0], a[1] = b[1], a[2] = b[2];
}
inline void IDFT(Number *a)
{
Number b[3];
b[0] = a[0] + a[1] + a[2];
b[2] = Number((1LL * a[0].x - a[1].y - a[2].x + a[2].y + (mod << 1)) % mod, (1LL * a[0].y + a[1].x - a[1].y - a[2].x + (mod << 1)) % mod);
b[1] = Number((1LL * a[0].x - a[1].x + a[1].y - a[2].y + (mod << 1)) % mod, (1LL * a[0].y - a[1].x + a[2].x - a[2].y + (mod << 1)) % mod);
a[0] = b[0], a[1] = b[1], a[2] = b[2];
}
inline void FWT(Number *x, int typ)
{
for (int i = 0; i < m; i ++)
for (int j = 0; j < n; j ++)
if (j / pwd[i] % 3 == 0)
{
Number t[3] = {x[j], x[j + pwd[i]], x[j + (pwd[i] << 1)]};
if (typ)
DFT(t);
else
IDFT(t);
x[j] = t[0], x[j + pwd[i]] = t[1], x[j + (pwd[i] << 1)] = t[2];
}
}
int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
m = Read(), t = Read(), mod = Read();
pwd[0] = 1;
for (int i = 1; i <= m; i ++)
pwd[i] = pwd[i - 1] * 3;
n = pwd[m];
for (int i = 0; i < n; i ++)
a[i].x = Read();
for (int i = 0; i <= m; i ++)
for (int j = 0; i + j <= m; j ++)
trans[i][j] = Read();
for (int i = 0; i < n; i ++)
cnx[i] = cnx[i / 3] + (i % 3 == 1), cny[i] = cny[i / 3] + (i % 3 == 2);
for (int i = 0; i < n; i ++)
b[i].x = trans[cnx[i]][cny[i]];
FWT(a, 0), FWT(b, 0);
for (int i = 0; i < n; i ++)
a[i] = a[i] * Qow(b[i], t);
FWT(a, 1);
int inv, tmp;
Exgcd(n, mod, inv, tmp);
inv = (inv + mod) % mod;
for (int i = 0; i < n; i ++)
printf("%d\n", 1LL * a[i].x * inv % mod);
return 0;
}