再探 Triple——2025.8.28 鲜花
再探 Triple
写完了,就提前发出来吧。
即刻轮回
いますぐ輪廻!!!
即刻轮回!!!
i ma su gu ri n ne
今回も結ばれないね…
这次也无法结合呢…
ko n ka i mo mu su ba re na i ne
嘘ついたら針千本 誓って
发誓说谎就吞千根针
u so tsu i ta ra ha ri se n bo n chi ka tte
ぜったい来世でまた会お?
来世绝对要再相见 好吗?
ze tta i ra i se de ma ta a o
いますぐ輪廻!!!
即刻轮回!!!
i ma su gu ri n ne
今回も結ばれないね…
这次也无法结合呢…
ko n ka i mo mu su ba re na i ne
全て 捨てて
全部丢弃
su be te su te te
「さらば 生まれ変わる」
「再见了 转世重生」
sa ra ba u ma re ka wa ru
「あまりに人生が 憂い」
「人生实在是过于 忧伤」
a ma ri ni ji n se i ga u re i
「君の指輪も白紙になって!」
「连你的戒指也变白纸了啊!」
ki mi no yu bi wa mo ha ku shi ni na tte
「せんぶ消えちゃって、
「全部消失
se n bu ki e cha tte
いいよ
也无妨
i i yo
「どうせ生まれ変わって」
「反正还能重生」
do u se u ma re ka wa tte
「巡って 出会って」
「轮回到再次相遇」
me gu tte de a tte
「宇宙が爆ぜてしまうまで」
「直至宇宙爆炸」
u chu u ga ha ze te shi ma u ma de
「何回も大好きになって」
「无数次爱上你」
na n ka i mo da i su ki ni na tte
「何回も大好きになって」
「无数次爱上你」
na n ka i mo da i su ki ni na tte
「毎回繰り返す身勝手」
「轮回往复的自私」
ma i ka i ku ri ka e su mi ga tte
「何回も大好きになって」
「无数次爱上你」
na n ka i mo da i su ki ni na tte
「ごめんね」
「对不起呐」
go me n ne
「メタモルフォーゼ」
「变身」
me ta mo ru fo o ze
いますぐ輪廻!!!
即刻轮回!!!
i ma su gu ri n ne
今回も結ばれないね★
这次也无法结合呢★
ko n ka i mo mu su ba re na i ne
嘘ついたら針千本 誓って
发誓说谎就吞千根针
u so tsu i ta ra ha ri se n bo n chi ka tte
ぜったい来世でまた会お★
来世绝对要再相见 好吗★
ze tta i ra i se de ma ta a o
いますぐ輪廻!!!
即刻轮回!!!
i ma su gu ri n ne
今回も結ばれないね★
这次也无法结合呢★
ko n ka i mo mu su ba re na i ne
全て 捨てて ぽいっ★
全部丢弃(丢)★
su be te su te te po i tsu
「だから 生まれ変われ」
「所以啊 转世重生吧」
da ka ra u ma re ka wa re
「間違った人生は 憂い」
「错误的人生只有 忧伤」
ma chi ga tta ji n se i wa u re i
「君の隣は私になって?」
「你身边的位置可以替换成我吗?」
ki mi no to na ri wa wa ta shi ni na tte
運命よ 跪け
命运啊 给我跪下
u n me i yo hi za ma zu ke
「いますぐ輪廻 今回も結ばれないね」
「即刻轮回 这次也无法结合呢」
i ma su gu ri n ne ko n ka i mo mu su ba re na i ne
「いますぐ輪廻 今回は報われないね」
「即刻轮回 这次也无法得偿所愿呢」
i ma su gu ri n ne ko n ka i wa mu ku wa re na i ne
「全て 捨てて
「全部丢弃
su be te su te te
いますぐしんで!
现在就去死吧!
i ma su gu shi n de
「ファンファーレが鳴って」
「号角声鸣」
fa n fa a re ga na tte
「大正解、おめでとう!」
「完全正确 恭喜你!」
da i se i ka i o me de to u
「ようやく君は救われる」
「你终于被拯救」
yo u ya ku ki mi wa su ku wa re ru
「来世でまた会おう★」
「来世再相见吧★」
ra i se de ma ta a o u
「いますぐ輪廻」
「即刻轮回」
i ma su gu ri n ne
「ちょっと苦しんで」
「稍微受点苦」
cho tto ku ru shi n de
「ツインレイなんだよ?!?!」
「我们可是双生火焰哦?!?!」
tsu i n re i na n da yo
早く
快点
ha ya ku
ねぇ
呐
ne e
「私と一つになろう」
「来和我合为一体吧」
wa ta shi to hi to tsu ni na ro u
「さぁ魂の浄化」
「来吧 让灵魂得到净化」
sa a ta ma shi i no jo u ka
「死への調和」
「与死亡的调和」
shi e no cho u wa
「どうか光になって」
「请化作光辉吧」
do u ka hi ka ri ni na tte
全て捨てて
全部丢弃
su be te su te te
「ぽいっ」
「(丢)」
po i tsu
很久以前有一篇 鲜花 写了 Triple 扩展,但当时我太菜了,写的啥也不是。
只能说 Triple 还是太牛了。
首先我们知道一下 FWT 变换一些基本知识。在 「快速数列变换这个词怎么造出来的」的一些阅读感悟 中我们已经提到过了,我们现在没有很好的适配最新张量做法的 Triple 做法,所以我们依然使用 \(c_{i, j} c_{i, k} = c_{i, j \circ k}\) 这个矩阵。
这里区分一下,定义 \(c'\) 表示 \(c\) 按位拆开后的位矩阵,有 \(c = \prod c'\)。
考虑一下 Triple 的流程,以下下标从 \(0\) 开始:
首先我们要求的是 \([x^p] \prod_i \sum_j c_{p, a_{i, j}} d_j\)。
我们显然是要把它拆开的,注意到 \(c\) 的值域很小,所以在一个 \(\sum\) 中 \(c_{p, a_{i, j}}\) 组成的序列只有 \(2^m\) 种可能,我们希望求出每种的出现次数。
先状压一下,这里若是按照大多数题解的做法的状压方法虽然会简单,但是不利于展现其普适性,我们这里采用二进制数 \(s\) 的第 \(p\) 位 \(s_p = 1\) 表示 \(c_{p, a_{i, p}} = 1\),\(s_p = 0\) 表示 \(c_{p, a_{i, p}} = -1\)。
设 \(t_s\) 表示 \(s\) 这种状态的出现次数,我们希望解出 \(t_s\),自然需要方程。
枚举 \(T \subseteq \{0, 1, \dots, m - 1\}\),将 \(z_{i} = \bigoplus_{j \in t} a_{i, j}\) 求 \({\rm FWT}(\sum_i x^{z_i})\),有 \([x^p]{\rm FWT}(\sum_i x^{z_i}) = \sum_i c_{p, z_i}\),将 \(c_{i, j} c_{i, k} = c_{i, j \circ k}\) 带入有 \(\sum_i c_{p, z_i} = \sum_i\prod_{j \in T} c_{p, a_{i, j}}\)。
感觉上这个已经和 \(t\) 有了千丝万缕的联系,考虑将其联系起来,容易发现其满足 \(\sum_i\prod_{j \in T} c_{p, a_{i, j}} = \sum_s f_{p, s}t_s\),这里 \(f_{p, s}\) 是一个贡献系数矩阵。
我们发现 \(\sum_s f_{p, s}t_s\) 和 FWT 的变换有着千丝万缕的联系,我们发现这个 \(f\) 竟然也是位矩阵,于是我们直接按位考虑将 \(f\) 拆成 \(f'\),将 \(f'\) 求逆做 IFWT 即可。
考虑这个流程可以做哪些运算,我们发现我们用到的性质只有 \(c_{i, j} c_{i, k} = c_{i, j \circ k}\) 和 \(c\) 的值域很小,并且 \(f'\) 得有逆。虽然我没仔细考虑,但感觉上 \(f'\) 有逆这个限制很容易满足,难点还是构造 \(c\),感觉是能扩展到一部分运算的。
给个【UNR #2】黎明前的巧克力的代码:
Code
/*
ulimit -s 1024000 && clear && g++ % -o %< -O2 -std=c++14 -DLOCAL -Wall -Wextra && ulimit -v 128000 && ./%<
ulimit -s 1024000 && clear && g++ % -o %< -O2 -std=c++14 -DLOCAL -Wall -Wextra -fsanitize=address,undefined -g && ./%<
echo && cat out.out && echo
*/
#include <bits/stdc++.h>
using namespace std;
using llt = long long;
using llf = long double;
using ull = unsigned long long;
#define endl '\n'
#ifdef LOCAL
FILE *InFile = freopen("in.in", "r", stdin), *OutFile = freopen("out.out", "w", stdout);
__attribute__((destructor)) void End_Put(){
cerr << "\nTime: " << clock() / 1000000. << "s\n";
assert(!system("grep VmPeak /proc/$PPID/status 1>&2"));
}
#endif
const int N = 1e6 + 3, M = 1 << 20 | 3, K = 2, MOD = 998244353, I2 = (MOD + 1) >> 1;
int Fpw(int a, int b){ int r = 1; for(; b; a = 1ll * a * a % MOD, b >>= 1) if(b & 1) r = 1ll * r * a % MOD; return r; }
int n, ck = 2, _a[N], ca[N][K], cd[K], sd[1 << K], ch[1 << K][M], sm[1 << K], tp[1 << K], aas[M];
void Fwt(int *f, int l, auto F){
for(int k = 1; k < l; k <<= 1)
for(int i = 0; i < l; i += (k << 1)) for(int j = 0; j < k; ++j)
F(f[i + j], f[i + j + k]);
}
void Xor(int &a, int &b){ tie(a, b) = make_pair((a + b) % MOD, (a - b) % MOD); }
void Ixr(int &a, int &b){ tie(a, b) = make_pair(1ll * (a + b) * I2 % MOD, 1ll * (a - b) * I2 % MOD); }
int main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n; cd[0] = 1, cd[1] = 2;
int _l = 1 << 20, _s = 1 << ck;
for(int s = 0; s < _s; ++s) for(int i = 0; i < ck; ++i) sd[s] += (s >> i & 1) ? -cd[i] : cd[i];
for(int i = 1; i <= n; ++i) cin >> ca[i][1], ca[i][0] = 0;
for(int i = 1; i <= n; ++i){
++ch[0][0];
for(int s = 1, _; s < _s; ++s)
++ch[s][sm[s] = sm[s ^ (s & -s)] ^ ca[i][__builtin_ctz(s)]];
}
for(int i = 0; i < _s; ++i) Fwt(ch[i], _l, Xor);
for(int i = 0; i < _l; ++i){
for(int s = 0; s < _s; ++s) tp[s] = ch[s][i];
Fwt(tp, _s, Ixr); int &ans = aas[i] = 1;
for(int s = 0; s < _s; ++s) ans = 1ll * ans * Fpw(sd[s], tp[s]) % MOD;
}
Fwt(aas, _l, Ixr);
cout << (aas[0] - 1 + MOD) % MOD;
}
P
本文来自博客园,作者:xrlong,转载请注明原文链接:https://www.cnblogs.com/xrlong/p/19061379
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。