UOJ#272. 【清华集训2016】石家庄的工人阶级队伍比较坚强
2017-10-13 20:55
483 查看
链接:
link题解:
直接讲构造FWT吧,其他都很简单不想说了。这里是做3进制异或,考虑分治乘。
T0=A0B0+A1B2+A2B1
T1=A0B1+A1B0+A2B2
T2=A0B2+A1B1+A2B0
如果使用待定系数法,用(A0+xA1+yA2)(B0+xB1+yB2)来构造,那么发现需要满足三个条件:
xy=1,x2=y,y2=x
这提示我们三次单位根。记w表示三次单位根,有:
记Ci=(A0+wiA1+w2iA2)(B0+wiB1+w2iB2),考虑用C构造出T。
注意到w2+w+1=0,
那么(1111ww21w2w)×(1111w2w1ww2)=3I,其中I是单位矩阵。
还有一个问题是w的处理,我们将数表示为a+bw,利用w2=−w−1就可以进行计算了。
这里只需要3在模p意义下有逆元即可,比题目的限制更松了。
代码:
#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; }
相关文章推荐
- uoj#272. 【清华集训2016】石家庄的工人阶级队伍比较坚强
- UOJ272 [清华集训2016] 石家庄的工人阶级队伍比较坚强 【分治乘法】
- UOJ268 [清华集训2016] 数据交互 【动态DP】【堆】【树链剖分】【线段树】
- UOJ276 [清华集训2016] 汽水 【二分答案】【点分治】【树状数组】
- UOJ#274. 【清华集训2016】温暖会指引我们前行
- 【BZOJ 4734】【UOJ 269】【清华集训2016】 如何优雅地求和
- UOJ274 [清华集训2016] 温暖会指引我们前行 【LCT】【最大生成树】
- UOJ 267 [清华集训2016]魔法小程序
- uoj#274. 【清华集训2016】温暖会指引我们前行 //LCT
- uoj#274. 【清华集训2016】温暖会指引我们前行
- UOJ_274_[清华集训2016]温暖会指引我们前行_LCT
- uoj275. 【清华集训2016】组合数问题
- UOJ #274. 【清华集训2016】温暖会指引我们前行 [lct]
- 【UOJ】#273. 【清华集训2016】你的生命已如风中残烛
- UOJ 274 【清华集训2016】温暖会指引我们前行 ——Link-Cut Tree
- uoj 279: [清华集训2016]温暖会指引我们前行
- uoj#46. 【清华集训2014】玄学
- UOJ275[清华集训2016]组合数问题
- uoj 41 【清华集训2014】矩阵变换 婚姻稳定问题
- BZOJ4730 UOJ#266【清华集训2016】Alice和Bob又在玩游戏