论在键盘的大部分标点符号都坏掉的情况下都可以做些什么

· · 休闲·娱乐

(本人平时并不擅长 C++,很多内容和真实语法有偏差,还请见谅。另外,本文中的符号指不能在 C++ 语言中作为变量名的可见字符。作为注释的 / 不被算作使用符号。)

起因

受到机房大佬的文章启发,我就在想既然排序都能用 %:<>()6 种符号实现,那解决逆序对又何尝不行呢?于是我就去寻找逆序对中优秀的实现,找到了可能比较好实现 3 种:

被淘汰的算法

归并排序需要用到递归,然而只用 %:<>() 想要实现递归是及其困难的,于是归并排序和线段树就遗憾离场了。

一些小技巧

要写树状数组,加减法,那么如何实现且保证复杂度呢?

替代运算符

在 C++ 中,有一种东西叫做替代运算符,下面是一些会用到的替代运算符:

运算符 替代运算符
& bitand
\| bitor
^ xor
~ compl
&= and_eq
\|= or_eq
^= xor_eq
\|\| or
! not

比较搞笑的是,bitand 还可以作为引用变量使用。

还有一些字符不是运算符,但是也可以被两个字符替代,这是早期 C++ 为了防止大家的键盘上没有一些字符而提供的。

原字符 替代字符
# %:
{ <%
} %>
[ <:
] :>

我们发现这些替代字符恰好都在允许使用的字符的范围内!

不过有很多运算符都是没有替代运算符的,但是我们可以自己实现,比如 a = b 就是 a xor_eq b xor aa == b 就是 not (a xor b)a <= b 就是 a < b or not (a xor b),等等。

加法

我们已经知道了替代运算符,那怎么用这些运算符完成加减法呢?首先,给出一种 O(\log V) 的加法。

我们发现在加法和异或的本质区别就是加法存在进位,因此我们可以将两个数的和转为异或和以及进位两个部分,即 a+b=a\ \mathrm{xor}\ b+2(a\ \mathrm{bitand}\ b),我们发现只要一直 a'\gets a\ \mathrm{xor}\ b,b'=2(a\ \mathrm{bitand}\ b),然后 a\gets a',b\gets b' 直到 a\ \mathrm{bitand}\ b=0 即可。

:::info[复杂度证明] 假设 a\ \mathrm{bitand}\ b 的最低位是 k

进行一步转化后 b'=2(a\ \mathrm{bitand}\ b) 的最低位是 k+1,此时 a'\ \mathrm{bitand}\ b' 的最低位一定会 >k,也就是说,一步转化至少会让 k 增加 1

我们发现 k 肯定不会超过 \left\lceil\log V\right\rceil,因此复杂度为 O(\log V)。 :::

while (a bitand b) <%
    if (a xor_eq b) <%%>
    if (b and_eq a xor b) <%%>
    if (b xor_eq b xor (b << 1)) <%%>
%>
if (a or_eq b) <%%>

在 C++ 中,-b=\mathrm{compl}\ b+1,因此我们可以将 a-b 转换为 a+\mathrm{compl}\ b+1

回到正题

接下来,我们就可以开始实现逆序对了!

需要用到的头文件:iostreamrangesvectoralgorithm,建议使用 C++ 20。

离散化

离散化同样有很多种实现,比如 lower_boundmap 和直接 sort 等等。这里我使用了手写 lower_bound 的方法。

先声明一些变量,由于有符号的限制,我们可以用 for (auto name : {x}) 来声明一个变量,也就是遍历一个只有一个元素的初始化列表。

for (int n : <%0%>)
for (long long ans : <%0%>) <%
    if (std::cin >> n) <%%>
    for (auto a : <%std::vector<int>(n)%>)
    for (auto b : <%std::vector<int>(n)%>)
    for (auto tr : <%std::vector<int>(n<<1)%>) <%

其中 tr 的下标从 1 开始,因此需要开到比 n 还大一点,刚好我们有 << 可以用,所以就开到了 n<<1

接下来就是真正的离散化部分了。

for (int i : std::views::iota(0) bitor std::views::take(n)) <%
    for (int l : <%0%>) for (int r : <%n%>) for (int res : <%0%>) <% // res 是二分结果
        for (int b : <%static_cast<int>(0xffffffffU)%>) <% // static_cast<int>(0xffffffffU) 是 -1,这段代码相当于 r--
            while (r bitand b) <%
                if (r xor_eq b) <%%>
                if (b and_eq r xor b) <%%>
                if (b xor_eq b xor (b << 1)) <%%>
            %>
            if (r or_eq b) <%%>
        %>
        while (l < r or not (l xor r)) <% // l <= r,闭区间二分
            for (int mid : <%l%>) <%
                // 这一部分相当于 mid = (l + r) >> 1
                for (int b : <%r%>) <%
                    while (mid bitand b) <%
                        if (mid xor_eq b) <%%>
                        if (b and_eq mid xor b) <%%>
                        if (b xor_eq b xor (b << 1)) <%%>
                    %>
                    if (mid or_eq b) <%%>
                %>
                if (mid xor_eq mid xor (mid >> 1)) <%%>
                // 二分判断,b[mid] >= a[i]
                if (b<:mid:> > a<:i:> or not (b<:mid:> xor a<:i:>)) <%
                    if (res xor_eq res xor mid) <%%> // res = mid
                    if (r xor_eq r xor mid) <%%> // r = mid
                    for (int b : <%static_cast<int>(0xffffffffU)%>) <% // r--
                        while (r bitand b) <%
                            if (r xor_eq b) <%%>
                            if (b and_eq r xor b) <%%>
                            if (b xor_eq b xor (b << 1)) <%%>
                        %>
                        if (r or_eq b) <%%>
                    %>
                %> else <%
                    if (l xor_eq l xor mid) <%%> // l = mid
                    for (int b : <%1%>) <% // l++
                        while (l bitand b) <%
                            if (l xor_eq b) <%%>
                            if (b and_eq l xor b) <%%>
                            if (b xor_eq b xor (b << 1)) <%%>
                        %>
                        if (l or_eq b) <%%>
                    %>
                %>
            %>
        %>
        if (a<:i:> xor_eq a<:i:> xor res) <%%> // a[i] = res
    %>
%>

树状数组

然后就是激动人心的树状数组部分了。树状数组的核心就是 lowbit,但是我们发现 lowbit(x) 显然硬求比 x & (-x) 更好写,常数更小,于是就可以这样实现:

for (auto l : <%1%>) <%
    while (not (x bitand 1)) <%
        if (l xor_eq l xor (l << 1)) {}
        if (x xor_eq x xor (x >> 1)) {}
    %>
%>

当然实际实现会有些不一样。

先声明变量

for (int i : std::views::iota(0) bitor std::views::take(n)) <%
    for (int x : <%a<:i:>%>) <%

然后由于树状数组的下标从 1 开始,于是我们需要将 x+1

for (int b : <%1%>) <%
    while (x bitand b) <%
        if (x xor_eq b) <%%>
        if (b and_eq x xor b) <%%>
        if (b xor_eq b xor (b << 1)) <%%>
    %>
    if (x or_eq b) <%%>
%>

正常的树状数组求 > x 的和需要用到总和减去 \le x 的和,然而我们不需要再写一次树状数组查出总和,因为第 i 个位置的总和就是 i-1,也就是当前的下标。于是需要先将答案 +i

for (long long b : <%i%>) <%
    while (ans bitand b) <%
        if (ans xor_eq b) <%%>
        if (b and_eq ans xor b) <%%>
        if (b xor_eq b xor (b << 1)) <%%>
    %>
    if (ans or_eq b) <%%>
%>

然后是查询 \le x 的和并更新答案。

for (int t : <%x%>) for (int l : <%0%>) <% // l 用于求 lowbit
    while (t) <%
        for (long long b : <%tr<:t:>%>) <% // ans += ~tr[t]
            if (b xor_eq b xor compl b) <%%>
            while (ans bitand b) <%
                if (ans xor_eq b) <%%>
                if (b and_eq ans xor b) <%%>
                if (b xor_eq b xor (b << 1)) <%%>
            %>
            if (ans or_eq b) <%%>
        %>
        for (long long b : <%1%>) <% // ans++,ans += ~tr[t]+1 相当于 ans -= tr[t]
            while (ans bitand b) <%
                if (ans xor_eq b) <%%>
                if (b and_eq ans xor b) <%%>
                if (b xor_eq b xor (b << 1)) <%%>
            %>
            if (ans or_eq b) <%%>
        %>
        if (l xor_eq l xor 1) <%%> // l = 1
        for (int tmp : <%t%>) <% // 求 l
            while (not (tmp bitand 1)) <%
                if (l xor_eq l xor (l << 1)) <%%>
                if (tmp xor_eq tmp xor (tmp >> 1)) <%%>
            %>
        %>
        if (t xor_eq l) <%%>
    %>
%>

最后是单点修改。

for (int t : <%x%>) for (int l : <%0%>) <%
    while (t < n or not (t xor n)) <% // t <= n
        for (int b : <%1%>) <% // tr[t]++
            while (tr<:t:> bitand b) <%
                if (tr<:t:> xor_eq b) <%%>
                if (b and_eq tr<:t:> xor b) <%%>
                if (b xor_eq b xor (b << 1)) <%%>
            %>
            if (tr<:t:> or_eq b) <%%>
        %>
        if (l xor_eq l xor 1) <%%> // l = 1
        for (int tmp : <%t%>) <% // 求 lowbit
            while (not (tmp bitand 1)) <%
                if (l xor_eq l xor (l << 1)) <%%>
                if (tmp xor_eq tmp xor (tmp >> 1)) <%%>
            %>
        %>
        while (t bitand l) <% // t += l
            if (t xor_eq l) <%%>
            if (l and_eq t xor l) <%%>
            if (l xor_eq l xor (l << 1)) <%%>
        %>
        if (t or_eq l) <%%> 
    %>
%>

完整代码

%:include<iostream>
%:include<ranges>
%:include<vector>
%:include<algorithm>

int main() <%
    if (std::ios::sync_with_stdio(0)) <%%>
    for (int n : <%0%>) for (long long ans : <%0%>) <%
        if (std::cin >> n) <%%>
        for (auto a : <%std::vector<int>(n)%>) for (auto b : <%std::vector<int>(n)%>) for (auto tr : <%std::vector<int>(n<<1)%>) <%
            for (auto bitand i : a) if (std::cin >> i) <%%>
            for (int i : std::views::iota(0) bitor std::views::take(n)) if (b<:i:> xor_eq a<:i:>) <%%>
            for (auto i : <%std::ranges::sort(b)%>) <%%>
            for (int i : std::views::iota(0) bitor std::views::take(n)) <%
                for (int l : <%0%>) for (int r : <%n%>) for (int res : <%0%>) <%
                    for (int b : <%static_cast<int>(0xffffffffU)%>) <%
                        while (r bitand b) <%
                            if (r xor_eq b) <%%>
                            if (b and_eq r xor b) <%%>
                            if (b xor_eq b xor (b << 1)) <%%>
                        %>
                        if (r or_eq b) <%%>
                    %>
                    while (l < r or not (l xor r)) <%
                        for (int mid : <%l%>) <%
                            for (int b : <%r%>) <%
                                while (mid bitand b) <%
                                    if (mid xor_eq b) <%%>
                                    if (b and_eq mid xor b) <%%>
                                    if (b xor_eq b xor (b << 1)) <%%>
                                %>
                                if (mid or_eq b) <%%>
                            %>
                            if (mid xor_eq mid xor (mid >> 1)) <%%>
                            if (b<:mid:> > a<:i:> or not (b<:mid:> xor a<:i:>)) <%
                                if (res xor_eq res xor mid) <%%>
                                if (r xor_eq r xor mid) <%%>
                                for (int b : <%static_cast<int>(0xffffffffU)%>) <%
                                    while (r bitand b) <%
                                        if (r xor_eq b) <%%>
                                        if (b and_eq r xor b) <%%>
                                        if (b xor_eq b xor (b << 1)) <%%>
                                    %>
                                    if (r or_eq b) <%%>
                                %>
                            %> else <%
                                if (l xor_eq l xor mid) <%%>
                                for (int b : <%1%>) <%
                                    while (l bitand b) <%
                                        if (l xor_eq b) <%%>
                                        if (b and_eq l xor b) <%%>
                                        if (b xor_eq b xor (b << 1)) <%%>
                                    %>
                                    if (l or_eq b) <%%>
                                %>
                            %>
                        %>
                    %>
                    if (a<:i:> xor_eq a<:i:> xor res) <%%>
                %>
            %>
            for (int i : std::views::iota(0) bitor std::views::take(n)) <%
                for (int x : <%a<:i:>%>) <%
                    for (int b : <%1%>) <%
                        while (x bitand b) <%
                            if (x xor_eq b) <%%>
                            if (b and_eq x xor b) <%%>
                            if (b xor_eq b xor (b << 1)) <%%>
                        %>
                        if (x or_eq b) <%%>
                    %>
                    for (long long b : <%i%>) <%
                        while (ans bitand b) <%
                            if (ans xor_eq b) <%%>
                            if (b and_eq ans xor b) <%%>
                            if (b xor_eq b xor (b << 1)) <%%>
                        %>
                        if (ans or_eq b) <%%>
                    %>
                    for (int t : <%x%>) for (int l : <%0%>) <%
                        while (t) <%
                            for (long long b : <%tr<:t:>%>) <%
                                if (b xor_eq b xor compl b) <%%>
                                while (ans bitand b) <%
                                    if (ans xor_eq b) <%%>
                                    if (b and_eq ans xor b) <%%>
                                    if (b xor_eq b xor (b << 1)) <%%>
                                %>
                                if (ans or_eq b) <%%>
                            %>
                            for (long long b : <%1%>) <%
                                while (ans bitand b) <%
                                    if (ans xor_eq b) <%%>
                                    if (b and_eq ans xor b) <%%>
                                    if (b xor_eq b xor (b << 1)) <%%>
                                %>
                                if (ans or_eq b) <%%>
                            %>
                            if (l xor_eq l xor 1) <%%>
                            for (int tmp : <%t%>) <%
                                while (not (tmp bitand 1)) <%
                                    if (l xor_eq l xor (l << 1)) <%%>
                                    if (tmp xor_eq tmp xor (tmp >> 1)) <%%>
                                %>
                            %>
                            if (t xor_eq l) <%%>
                        %>
                    %>
                    for (int t : <%x%>) for (int l : <%0%>) <%
                        while (t < n or not (t xor n)) <%
                            for (int b : <%1%>) <%
                                while (tr<:t:> bitand b) <%
                                    if (tr<:t:> xor_eq b) <%%>
                                    if (b and_eq tr<:t:> xor b) <%%>
                                    if (b xor_eq b xor (b << 1)) <%%>
                                %>
                                if (tr<:t:> or_eq b) <%%>
                            %>
                            if (l xor_eq l xor 1) <%%>
                            for (int tmp : <%t%>) <%
                                while (not (tmp bitand 1)) <%
                                    if (l xor_eq l xor (l << 1)) <%%>
                                    if (tmp xor_eq tmp xor (tmp >> 1)) <%%>
                                %>
                            %>
                            while (t bitand l) <%
                                if (t xor_eq l) <%%>
                                if (l and_eq t xor l) <%%>
                                if (l xor_eq l xor (l << 1)) <%%>
                            %>
                            if (t or_eq l) <%%>
                        %>
                    %>
                %>
            %>
            if (std::cout << ans) <%%>
        %> 
    %>
%>

提交记录:点这里。

更多的思考

除了刚才那三个算法,难道就没有可以用的算法了吗?当然有!我们可以使用分块!虽然 O(n\sqrt n\log n) 只能获得 50 分,但是这也给了我们启发:分块是可以用六种特殊字符完成的。

由于没有满分,就不放提交记录了,只给出完整代码,感兴趣的读者可以尝试优化到满分(虽然不太可能)。

%:include<iostream>
%:include<algorithm>
%:include<ranges>
%:include<cmath>
%:include<vector>

int main() <%
    if (std::ios::sync_with_stdio(0)) <%%>
    for (int n : <%0%>) if (std::cin >> n) 
    for (int B : <%std::sqrt(n)%>) 
    for (long long ans : <%0%>)
    for (auto a : std::array<%std::vector<int>(n)%>)
    for (auto b : <%std::vector<int>(n)%>)
    for (auto sum : <%std::vector<int>(n)%>)
    for (auto mp : <%std::vector<int>(n)%>)
    for (auto pos : <%std::vector<int>(n)%>)
    for (auto l : <%std::vector<int>(n)%>)
    for (auto r : <%std::vector<int>(n)%>) <%
        for (auto bitand i : a) if (std::cin >> i) <%%> 
        for (int i : std::views::iota(0) bitor std::views::take(n)) if (b<:i:> xor_eq a<:i:>) <%%>
        for (auto i : <%std::ranges::sort(b)%>) <%%>
        for (int i : std::views::iota(0) bitor std::views::take(n)) <%
            for (int l : <%0%>)
            for (int r : <%n%>) 
            for (int res : <%0%>) <%
                for (int b : <%0xffffffff%>) <% while (r bitand b) <% if (r xor_eq b) <%%> if (b and_eq r xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (r or_eq b) <%%> %>
                while (l < r or not (l xor r)) <%
                    for (int mid : <%l%>) <%
                        for (int b : <%r%>) <% while (mid bitand b) <% if (mid xor_eq b) <%%> if (b and_eq mid xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (mid or_eq b) <%%> %>
                        if (mid xor_eq mid xor (mid >> 1)) <%%>
                        if (b<:mid:> > a<:i:> or not (b<:mid:> xor a<:i:>)) <%
                            if (r xor_eq r xor mid) <%%>
                            for (int b : <%0xffffffff%>) <% while (r bitand b) <% if (r xor_eq b) <%%> if (b and_eq r xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (r or_eq b) <%%> %>
                            if (res xor_eq res xor mid) <%%>
                        %> else <%
                            if (l xor_eq l xor mid) <%%>
                            for (int b : <%1%>) <% while (l bitand b) <% if (l xor_eq b) <%%> if (b and_eq l xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (l or_eq b) <%%> %>
                        %>
                    %>
                %>
                if (a<:i:> xor_eq a<:i:> xor res) <%%>
            %>
        %>
        for (int i : <%0%>) 
        for (int t : <%0%>) <%
            while (i < n) <%
                for (int b : <%1%>) <% while (t bitand b) <% if (t xor_eq b) <%%> if (b and_eq t xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (t or_eq b) <%%> %>if (l<:t:> xor_eq i) <%%> 
                for (int j : <%i%>) <%
                    for (int b : <%B%>) <% while (i bitand b) <% if (i xor_eq b) <%%> if (b and_eq i xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (i or_eq b) <%%> %>
                    while (j < i and j < n) <%
                        if (pos<:j:> xor_eq t) <%%>
                        if (r<:t:> xor_eq r<:t:> xor j) <%%>
                        for (int b : <%1%>) <% while (j bitand b) <% if (j xor_eq b) <%%> if (b and_eq j xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (j or_eq b) <%%> %>
                    %>
                %>
            %>
        %>
        for (int i : std::views::iota(0) bitor std::views::take(n)) <%
            for (long long b : <%i%>) <% while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>
            if (pos<:a<:i:>:> xor 1) <%
                for (int j : <%0%>) while (j < r<:1:> or not (j xor r<:1:>)) <%
                    for (long long b : <%mp<:j:>%>) <% if (b xor_eq b xor compl b) <%%> while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>            
                    for (int b : <%1%>) <% while (j bitand b) <% if (j xor_eq b) <%%> if (b and_eq j xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (j or_eq b) <%%> %>
                    for (long long b : <%1%>) <% while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>
                %>
                for (int j : <%2%>) while (j < pos<:a<:i:>:>) <%
                    for (long long b : <%sum<:j:>%>) <% if (b xor_eq b xor compl b) <%%> while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>
                    for (int b : <%1%>) <% while (j bitand b) <% if (j xor_eq b) <%%> if (b and_eq j xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (j or_eq b) <%%> %>
                    for (long long b : <%1%>) <% while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>
                %>
                for (int j : <%l<:pos<:a<:i:>:>:>%>) while (j < a<:i:> or not (j xor a<:i:>)) <%
                    for (long long b : <%mp<:j:>%>) <% if (b xor_eq b xor compl b) <%%> while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>            
                    for (int b : <%1%>) <% while (j bitand b) <% if (j xor_eq b) <%%> if (b and_eq j xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (j or_eq b) <%%> %>
                    for (long long b : <%1%>) <% while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>
                %>
            %> else <%
                for (int j : <%0%>) while (j < a<:i:> or not (j xor a<:i:>)) <%
                    for (long long b : <%mp<:j:>%>) <% if (b xor_eq b xor compl b) <%%> while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>
                    for (int b : <%1%>) <% while (j bitand b) <% if (j xor_eq b) <%%> if (b and_eq j xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (j or_eq b) <%%> %>
                    for (long long b : <%1%>) <% while (ans bitand b) <% if (ans xor_eq b) <%%> if (b and_eq ans xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (ans or_eq b) <%%> %>
                %>
            %>
            for (int b : <%1%>) <% while (mp<:a<:i:>:> bitand b) <% if (mp<:a<:i:>:> xor_eq b) <%%> if (b and_eq mp<:a<:i:>:> xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (mp<:a<:i:>:> or_eq b) <%%> %>
            for (int b : <%1%>) <% while (sum<:pos<:a<:i:>:>:> bitand b) <% if (sum<:pos<:a<:i:>:>:> xor_eq b) <%%> if (b and_eq sum<:pos<:a<:i:>:>:> xor b) <%%> if (b xor_eq b xor (b << 1)) <%%> %> if (sum<:pos<:a<:i:>:>:> or_eq b) <%%> %>
        %>
        if (std::cout << ans) <%%>
    %> 
%>

更加困难的挑战

相信大家一定听说过一种超级考验码力、耐心和调试能力的题型,没错,就是大模拟!这里我选用了一个比较有代表性的题目:P2586 [ZJOI2008] 杀蚂蚁。

题目坑点

这里说的是常规的代码需要注意的地方。

  1. 题目没说 nm 的含义 可能是我眼瞎没看见,我们猜测 n 是行,m 是列,发现猜对了(根据样例),我们继续猜测东方向是让列 +1,又猜对了。
  2. 如果此时仍有多种选择,蚂蚁先面向正东,如果正东不是可选择的某个方向,它会顺时针转 90^\degree,再次判断,如果还不是,再顺时针旋转 90^\degree,直到找到可以去的方向。

    注意这里的“可选择的方向”不是指可达点,而是可达点中信息素最大的。可能是我语文太差了这个破地方调了半天

  3. 激光塔有个比较奇怪的特性:它在选定了打击目标后,只要目标在其射程内,塔到目标蚂蚁圆心的连线上的所有蚂蚁(这里“被打到”的判定变成了表示激光的线段与表示蚂蚁的圆有公共点)都会被打到并损 d 格血,但激光不会穿透它的打击目标打到后面的蚂蚁。

    没错,我又看错成和圆心有公共点了,直接用 \gcd 打蚂蚁了,后面调了半天发现还要用一点数学知识判断圆心和直线的距离。

优化运算

在逆序对中,我们成功写出了 O(\log V) 的加法,但这还是太慢了,我们需要 O(1) 的加法!

首先,我们需要处理一个 nxt 数组和一个 pre 数组,nxt_i=i+1,pre_i=i-1

这是好处理的,我们只需要让 i1 枚举到 10^6,同步维护一个 lst 表示 i-1lst 初始值是 0,每次让 pre_i\gets lst,nxt_{lst}\gets i,然后让 lst\gets i

血量的变化需要 -d,这用常规的做法也要带 \log,因此我们需要维护数组 jd_i(减 d)表示 i-d,维护方式和 pre 差不多,不过多赘述。

接下来,实现加减法,我们设 zh_{a,b}(总和)表示 a+bcj_{a,b}(差距)表示 |a-b|。则有递推公式:

注意一下边界条件即可。

最后是乘法 mul_{i,j}=ij 和平方 pw_{i}=i^2=mul_{i,i},递推公式:mul_{i,j}=mul_{i,j-1}+i

注意二维数组很难实现,于是我们将编号压成一维数组,用 zh[(i<<8)|j]cj[(i<<8)|j] 代替刚刚的 zh[i][j]cj[i][j],用 mul[(i<<7)|j] 代替刚刚的 mul[i][j]

代码:

for (int lst : <%0%>) <%
    if (pre<:0:> xor_eq compl 0) <%%>
    for (int i : std::views::iota(1) bitor std::views::take(1000000)) <%
        if (pre<:i:> xor_eq lst) <%%>
        if (nxt<:lst:> xor_eq i) <%%>
        if (lst xor_eq lst xor i) <%%>
    %>
%>

for (int i : std::views::iota(1) bitor std::views::take(200)) <%
    if (zh<:i:> xor_eq i) <%%>
    if (cj<:i:> xor_eq i) <%%>
%>

for (int i : std::views::iota(1) bitor std::views::take(200)) <%
    if (zh<:i<<8:> xor_eq i) <%%>
    if (cj<:i<<8:> xor_eq i) <%%>
    for (int lst : <%0%>) for (int j : std::views::iota(1) bitor std::views::take(200)) <%
        if (zh<:(i<<8) bitor j:> xor_eq nxt<:zh<:(i<<8) bitor lst:>:>) <%%>
        if (i < j) <%
            if (cj<:(i<<8) bitor j:> xor_eq nxt<:cj<:(i<<8) bitor lst:>:>) <%%>
        %> else <%
            if (cj<:(i<<8) bitor j:> xor_eq pre<:cj<:(i<<8) bitor lst:>:>) <%%>
        %>
        if (lst xor_eq lst xor j) <%%>
    %>
%>

for (int i : std::views::iota(1) bitor std::views::take(100)) <%
    for (int lst : <%0%>) for (int j : std::views::iota(1) bitor std::views::take(100)) <%
        if (mul<:(i<<7) bitor j:> xor_eq mul<:(i<<7) bitor lst:>) <%%>
        for (int b : <%i%>) <%
            while (mul<:(i<<7) bitor j:> bitand b) <%
                if (mul<:(i<<7) bitor j:> xor_eq b) <%%>
                if (b and_eq mul<:(i<<7) bitor j:> xor b) <%%>
                if (b xor_eq b xor (b << 1)) <%%>
            %>
            if (mul<:(i<<7) bitor j:> or_eq b) <%%>
        %>
        if (lst xor_eq lst xor j) <%%>
    %>
    if (pw<:i:> xor_eq mul<:(i<<7) bitor i:>) <%%>
%>

代码逻辑

由于给大模拟写题解是困难的事,因此我就说说每个东西都维护什么,其它东西就看你和它有没有缘分了~

// 导入一堆头文件
%:include<iostream>
%:include<vector>
%:include<ranges>
%:include<algorithm>
%:include<climits>
// %:x 相当于 "x",只不过为了省掉 ",只能这么写
%:define str(x) %:x
%:define N 200010

int main() <%
    for (int n : <%0%>)
    for (int m : <%0%>)
    for (int s : <%0%>)
    for (int d : <%0%>)
    for (int r : <%0%>)
    for (int ed : <%0%>) // 蚂蚁是否胜利
    for (int mysl : <%0%>) // 活着的蚂蚁数量
    for (bool ndg : <%0%>) // 蛋糕有没有被拿
    for (int sj : <%0%>) // 当前时间
    for (int t : <%0%>) 
    for (int cnt : <%0%>) // 累计出生的蚂蚁数量 % 6
    for (int tot : <%0%>) // 当前蚂蚁的等级
    for (auto dj : <%std::vector<int>(N)%>) // 等级
    for (auto nl : <%std::vector<int>(N)%>) // 年龄
    for (auto ml : <%std::vector<int>(N)%>) // 活动时间 % 5
    for (auto xl : <%std::vector<int>(N)%>) // 血量
    for (auto zdxl : <%std::vector<int>(N)%>) // 最大血量,可以证明在 int 范围内
    for (auto x : <%std::vector<int>(N)%>)
    for (auto y : <%std::vector<int>(N)%>)
    for (auto px : <%std::vector<int>(N)%>) // 炮塔坐标
    for (auto py : <%std::vector<int>(N)%>)
    for (auto lx : <%std::vector<int>(N)%>) // 上一秒的蚂蚁坐标
    for (auto ly : <%std::vector<int>(N)%>)
    for (auto mp : <%std::vector<int>(300)%>) // 二维数组压成一维,mp[(i<<4)|j] 表示 (i,j) 上的蚂蚁编号,如果没有就是 0
    for (auto pt : <%std::vector<int>(300)%>) // 同上,这个是是否有炮塔
    for (auto xxs : <%std::vector<int>(300)%>) // 同上,这个是信息素
    for (auto dg : <%std::vector<int>(N)%>) // 是否有蛋糕
    for (auto dx : <%std::vector<int>(4)%>) // 东南西北偏移量
    for (auto dy : <%std::vector<int>(4)%>) 
    for (auto nxt : <%std::vector<int>(1000005)%>) // nxt[i] = i+1
    for (auto pre : <%std::vector<int>(1000005)%>) // pre[i] = i-1
    for (auto mul : <%std::vector<int>(N)%>)
    for (auto zh : <%std::vector<int>(N)%>)
    for (auto cj : <%std::vector<int>(N)%>)
    for (auto pw : <%std::vector<int>(N)%>)
    for (auto jd : <%std::vector<int>(50010005)%>)
    for (auto z : <%std::vector<int>(205)%>) <% // 代表等级为 i 的最大血量

接下来就是完整代码啦~

// 导入一堆头文件
%:include<iostream>
%:include<vector>
%:include<ranges>
%:include<algorithm>
%:include<climits>
// %:x 相当于 "x",只不过为了省掉 ",只能这么写
%:define str(x) %:x
%:define N 200010

int main() <%
    for (int n : <%0%>)
    for (int m : <%0%>)
    for (int s : <%0%>)
    for (int d : <%0%>)
    for (int r : <%0%>)
    for (int ed : <%0%>) // 蚂蚁是否胜利
    for (int mysl : <%0%>) // 活着的蚂蚁数量
    for (bool ndg : <%0%>) // 蛋糕有没有被拿
    for (int sj : <%0%>) // 当前时间
    for (int t : <%0%>) 
    for (int cnt : <%0%>) // 累计出生的蚂蚁数量 % 6
    for (int tot : <%0%>) // 当前蚂蚁的等级
    for (auto dj : <%std::vector<int>(N)%>) // 等级
    for (auto nl : <%std::vector<int>(N)%>) // 年龄
    for (auto ml : <%std::vector<int>(N)%>) // 活动时间 % 5
    for (auto xl : <%std::vector<int>(N)%>) // 血量
    for (auto zdxl : <%std::vector<int>(N)%>) // 最大血量,可以证明在 int 范围内
    for (auto x : <%std::vector<int>(N)%>)
    for (auto y : <%std::vector<int>(N)%>)
    for (auto px : <%std::vector<int>(N)%>) // 炮塔坐标
    for (auto py : <%std::vector<int>(N)%>)
    for (auto lx : <%std::vector<int>(N)%>) // 上一秒的蚂蚁坐标
    for (auto ly : <%std::vector<int>(N)%>)
    for (auto mp : <%std::vector<int>(300)%>) // 二维数组压成一维,mp[(i<<4)|j] 表示 (i,j) 上的蚂蚁编号,如果没有就是 0
    for (auto pt : <%std::vector<int>(300)%>) // 同上,这个是是否有炮塔
    for (auto xxs : <%std::vector<int>(300)%>) // 同上,这个是信息素
    for (auto dg : <%std::vector<int>(N)%>) // 是否有蛋糕
    for (auto dx : <%std::vector<int>(4)%>) // 东南西北偏移量
    for (auto dy : <%std::vector<int>(4)%>) 
    for (auto nxt : <%std::vector<int>(1000005)%>) // nxt[i] = i+1
    for (auto pre : <%std::vector<int>(1000005)%>) // pre[i] = i-1
    for (auto mul : <%std::vector<int>(N)%>) // mul[(i<<7)|j] = i*j
    for (auto zh : <%std::vector<int>(N)%>) // zh[(i<<8)|j] = i+j
    for (auto cj : <%std::vector<int>(N)%>) // 同上,这个是 abs(i-j)
    for (auto pw : <%std::vector<int>(N)%>) // pw[i] = i*i
    for (auto jd : <%std::vector<int>(50010005)%>) // jd[i] = i-d
    for (auto z : <%std::vector<int>(205)%>) <% // 代表等级为 i 的最大血量
        // 数组的初始化
        for (int lst : <%0%>) <%
            if (pre<:0:> xor_eq compl 0) <%%>
            for (int i : std::views::iota(1) bitor std::views::take(1000000)) <%
                if (pre<:i:> xor_eq lst) <%%>
                if (nxt<:lst:> xor_eq i) <%%>
                if (lst xor_eq lst xor i) <%%>
            %>
        %>
        for (int i : std::views::iota(1) bitor std::views::take(200)) <%
            if (zh<:i:> xor_eq i) <%%>
            if (cj<:i:> xor_eq i) <%%>
        %>
        for (int i : std::views::iota(1) bitor std::views::take(200)) <%
            if (zh<:i<<8:> xor_eq i) <%%>
            if (cj<:i<<8:> xor_eq i) <%%>
            for (int lst : <%0%>) for (int j : std::views::iota(1) bitor std::views::take(200)) <%
                if (zh<:(i<<8) bitor j:> xor_eq nxt<:zh<:(i<<8) bitor lst:>:>) <%%>
                if (i < j) <%
                    if (cj<:(i<<8) bitor j:> xor_eq nxt<:cj<:(i<<8) bitor lst:>:>) <%%>
                %> else <%
                    if (cj<:(i<<8) bitor j:> xor_eq pre<:cj<:(i<<8) bitor lst:>:>) <%%>
                %>
                if (lst xor_eq lst xor j) <%%>
            %>
        %>
        for (int i : std::views::iota(1) bitor std::views::take(100)) <%
            for (int lst : <%0%>) for (int j : std::views::iota(1) bitor std::views::take(100)) <%
                if (mul<:(i<<7) bitor j:> xor_eq mul<:(i<<7) bitor lst:>) <%%>
                for (int b : <%i%>) <%
                    while (mul<:(i<<7) bitor j:> bitand b) <%
                        if (mul<:(i<<7) bitor j:> xor_eq b) <%%>
                        if (b and_eq mul<:(i<<7) bitor j:> xor b) <%%>
                        if (b xor_eq b xor (b << 1)) <%%>
                    %>
                    if (mul<:(i<<7) bitor j:> or_eq b) <%%>
                %>
                if (lst xor_eq lst xor j) <%%>
            %>
            if (pw<:i:> xor_eq mul<:(i<<7) bitor i:>) <%%>
        %>
        // 这一部分本应该是 z 数组的打表,太长省略了
        if (std::ios::sync_with_stdio(0)) <%%>
        if (dx<:1:> xor_eq 1) <%%>
        if (dx<:3:> xor_eq compl 0) <%%>
        if (dy<:0:> xor_eq 1) <%%>
        if (dy<:2:> xor_eq compl 0) <%%>
        if (std::cin >> n >> m >> s >> d >> r) <%%>
        for (int lst : <%d%>) for (int i : std::views::iota(d) bitor std::views::take(50000000)) <%
            if (i xor d) if (jd<:i:> xor_eq nxt<:jd<:lst:>:>) <%%>
            if (lst xor_eq lst xor i) <%%>
        %>
        for (int i : std::views::iota(1) bitor std::views::take(s)) <%
            if (std::cin >> px<:i:> >> py<:i:>) <%%>
            if (pt<:(px<:i:><<4) bitor py<:i:>:> xor_eq 1) <%%> 
        %>
        if (std::cin >> t) <%%>
        while (t and not ed) <%
            if (t xor_eq t xor pre<:t:>) <%%>
            if (sj xor_eq sj xor nxt<:sj:>) <%%>
            // 蚂蚁出生
            if (mysl < 6 and not mp<:0:>) <%
                if (mysl xor_eq mysl xor nxt<:mysl:>) <%%>
                if (cnt xor_eq cnt xor nxt<:cnt:>) <%%>
                if (not (cnt xor 1)) if (tot xor_eq nxt<:tot:> xor tot) <%%>
                if (not (cnt xor 6)) if (cnt and_eq 0) <%%>
                if (dj<:mysl:> xor_eq tot xor dj<:mysl:>) <%%>
                if (xl<:mysl:> xor_eq xl<:mysl:> xor z<:tot:>) <%%>
                if (zdxl<:mysl:> xor_eq zdxl<:mysl:> xor z<:tot:>) <%%>
                if (x<:mysl:> and_eq 0) <%%>
                if (y<:mysl:> and_eq 0) <%%>
                if (dg<:mysl:> and_eq 0) <%%>
                if (nl<:mysl:> and_eq 0) <%%>
                if (ml<:mysl:> xor_eq ml<:mysl:> xor 1) <%%>
                if (lx<:mysl:> xor_eq lx<:mysl:> xor compl 0) <%%>
                if (ly<:mysl:> xor_eq ly<:mysl:> xor compl 0) <%%>
                if (mp<:0:> xor_eq mp<:0:> xor mysl) <%%>
            %>
            // 蚂蚁移动
            for (int i : std::views::iota(1) bitor std::views::take(mysl)) <%
                if (dg<:i:>) <% if (xxs<:(x<:i:><<4) bitor y<:i:>:> xor_eq nxt<:nxt<:nxt<:nxt<:nxt<:xxs<:(x<:i:><<4) bitor y<:i:>:>:>:>:>:>:> xor xxs<:(x<:i:><<4) bitor y<:i:>:>) <%%> %>
                else if (xxs<:(x<:i:><<4) bitor y<:i:>:> xor_eq nxt<:nxt<:xxs<:(x<:i:><<4) bitor y<:i:>:>:>:> xor xxs<:(x<:i:><<4) bitor y<:i:>:>) <%%>
            %>
            for (int i : std::views::iota(1) bitor std::views::take(mysl)) for (int xz : <%4%>) for (int id : <%0%>) <%
                for (int j : std::views::iota(0) bitor std::views::take(4)) for (int nx : <%x<:i:>%>) for (int ny : <%y<:i:>%>) <%
                    if (not (dx<:j:> xor 1)) <% if (nx xor_eq nx xor nxt<:nx:>) <%%> %>
                    else if (dx<:j:>) <% if (nx xor_eq nx xor pre<:nx:>) <%%> %>
                    if (not (dy<:j:> xor 1)) <% if (ny xor_eq ny xor nxt<:ny:>) <%%> %>
                    else if (dy<:j:>) <% if (ny xor_eq ny xor pre<:ny:>) <%%> %>
                    if (nx < 0 or ny < 0 or nx > n or ny > m or mp<:(nx<<4) bitor ny:> or pt<:(nx<<4) bitor ny:> or (not (nx xor lx<:i:>) and not (ny xor ly<:i:>))) <% if (xz xor_eq xz xor pre<:xz:>) <%%> %>
                    else if (id xor_eq id xor j) <%%>
                %>
                if (not (xz xor 1)) <%
                    if (mp<:(x<:i:><<4) bitor y<:i:>:> and_eq 0) <%%>
                    if (lx<:i:> xor_eq lx<:i:> xor x<:i:>) <%%>
                    if (ly<:i:> xor_eq ly<:i:> xor y<:i:>) <%%>
                    if (not (dx<:id:> xor 1)) <% if (x<:i:> xor_eq x<:i:> xor nxt<:x<:i:>:>) <%%> %>
                    else if (dx<:id:>) <% if (x<:i:> xor_eq x<:i:> xor pre<:x<:i:>:>) <%%> %>
                    if (not (dy<:id:> xor 1)) <% if (y<:i:> xor_eq y<:i:> xor nxt<:y<:i:>:>) <%%> %>
                    else if (dy<:id:>) <% if (y<:i:> xor_eq y<:i:> xor pre<:y<:i:>:>) <%%> %>
                    if (mp<:(x<:i:><<4) bitor y<:i:>:> xor_eq mp<:(x<:i:><<4) bitor y<:i:>:> xor i) <%%>
                    if (not ndg and not (x<:i:> xor n) and not (y<:i:> xor m)) <%
                        if (ndg xor_eq 1) <%%>
                        if (dg<:i:> xor_eq 1) <%%>
                        for (auto b : <%zdxl<:i:> >> 1%>) <% while (xl<:i:> bitand b) <% if (xl<:i:> xor_eq b) <%%> if (b and_eq xl<:i:> xor b) <%%> if (b xor_eq b xor (b << 1)) <%%>%> if (xl<:i:> or_eq b) <%%> %>
                        if (xl<:i:> > zdxl<:i:>) if (xl<:i:> xor_eq xl<:i:> xor zdxl<:i:>) <%%>
                    %>
                %> else if (not xz) <%
                    if (lx<:i:> xor_eq lx<:i:> xor x<:i:>) <%%>
                    if (ly<:i:> xor_eq ly<:i:> xor y<:i:>) <%%>
                    if (not ndg and not (x<:i:> xor n) and not (y<:i:> xor m)) <%
                        if (ndg xor_eq 1) <%%>
                        if (dg<:i:> xor_eq 1) <%%>
                        for (auto b : <%zdxl<:i:> >> 1%>) <% while (xl<:i:> bitand b) <% if (xl<:i:> xor_eq b) <%%> if (b and_eq xl<:i:> xor b) <%%> if (b xor_eq b xor (b << 1)) <%%>%> if (xl<:i:> or_eq b) <%%> %>
                        if (xl<:i:> > zdxl<:i:>) if (xl<:i:> xor_eq xl<:i:> xor zdxl<:i:>) <%%>
                    %>
                %> else for (int mx : <%0%>) for (int num : <%0%>) <%
                    for (int j : std::views::iota(0) bitor std::views::take(4)) for (int nx : <%x<:i:>%>) for (int ny : <%y<:i:>%>) <%
                        if (not (dx<:j:> xor 1)) <% if (nx xor_eq nx xor nxt<:nx:>) <%%> %>
                        else if (dx<:j:>) <% if (nx xor_eq nx xor pre<:nx:>) <%%> %>
                        if (not (dy<:j:> xor 1)) <% if (ny xor_eq ny xor nxt<:ny:>) <%%> %>
                        else if (dy<:j:>) <% if (ny xor_eq ny xor pre<:ny:>) <%%> %>
                        if (not (nx < 0 or ny < 0 or nx > n or ny > m or mp<:(nx<<4) bitor ny:> or pt<:(nx<<4) bitor ny:> or (not (nx xor lx<:i:>) and not (ny xor ly<:i:>)))) <%
                            if (xxs<:(nx<<4) bitor ny:> > mx) <%
                                if (mx xor_eq mx xor xxs<:(nx<<4) bitor ny:>) <%%>
                                if (num xor_eq num xor 1) <%%>
                                if (id xor_eq id xor j) <%%>
                            %> else if (not (xxs<:(nx<<4) bitor ny:> xor mx)) <%
                                if (num xor_eq num xor nxt<:num:>) <%%>
                            %>
                        %>
                    %>
                    if (not (num xor 1)) <%
                        if (not ml<:i:>) <%
                            for (int fd : <%0%>) for (int j : <%id%>) for (int k : std::views::iota(0) bitor std::views::take(4)) for (int nx : <%x<:i:>%>) for (int ny : <%y<:i:>%>) <%
                                if (j xor_eq j xor pre<:j:>) <%%>
                                if (j < 0) <% if (j xor_eq j xor 3) <%%> %>
                                if (not (dx<:j:> xor 1)) <% if (nx xor_eq nx xor nxt<:nx:>) <%%> %>
                                else if (dx<:j:>) <% if (nx xor_eq nx xor pre<:nx:>) <%%> %>
                                if (not (dy<:j:> xor 1)) <% if (ny xor_eq ny xor nxt<:ny:>) <%%> %>
                                else if (dy<:j:>) <% if (ny xor_eq ny xor pre<:ny:>) <%%> %>
                                if (not (fd or nx < 0 or ny < 0 or nx > n or ny > m or mp<:(nx<<4) bitor ny:> or pt<:(nx<<4) bitor ny:> or (not (nx xor lx<:i:>) and not (ny xor ly<:i:>)))) <%
                                    if (id xor_eq id xor j) <%%>
                                    if (fd xor_eq fd xor 1) <%%>
                                %>
                            %>
                        %>
                        if (mp<:(x<:i:><<4) bitor y<:i:>:> and_eq 0) <%%>
                        if (lx<:i:> xor_eq lx<:i:> xor x<:i:>) <%%>
                        if (ly<:i:> xor_eq ly<:i:> xor y<:i:>) <%%>
                        if (not (dx<:id:> xor 1)) <% if (x<:i:> xor_eq x<:i:> xor nxt<:x<:i:>:>) <%%> %>
                        else if (dx<:id:>) <% if (x<:i:> xor_eq x<:i:> xor pre<:x<:i:>:>) <%%> %>
                        if (not (dy<:id:> xor 1)) <% if (y<:i:> xor_eq y<:i:> xor nxt<:y<:i:>:>) <%%> %>
                        else if (dy<:id:>) <% if (y<:i:> xor_eq y<:i:> xor pre<:y<:i:>:>) <%%> %>
                        if (mp<:(x<:i:><<4) bitor y<:i:>:> xor_eq mp<:(x<:i:><<4) bitor y<:i:>:> xor i) <%%>
                        if (not ndg and not (x<:i:> xor n) and not (y<:i:> xor m)) <%
                            if (ndg xor_eq 1) <%%>
                            if (dg<:i:> xor_eq 1) <%%>
                            for (auto b : <%zdxl<:i:> >> 1%>) <% while (xl<:i:> bitand b) <% if (xl<:i:> xor_eq b) <%%> if (b and_eq xl<:i:> xor b) <%%> if (b xor_eq b xor (b << 1)) <%%>%> if (xl<:i:> or_eq b) <%%> %>
                            if (xl<:i:> > zdxl<:i:>) if (xl<:i:> xor_eq xl<:i:> xor zdxl<:i:>) <%%>
                        %>
                    %> else <%
                        for (int fd : <%0%>) for (int j : std::views::iota(0) bitor std::views::take(4)) for (int nx : <%x<:i:>%>) for (int ny : <%y<:i:>%>) <%
                            if (not (dx<:j:> xor 1)) <% if (nx xor_eq nx xor nxt<:nx:>) <%%> %>
                            else if (dx<:j:>) <% if (nx xor_eq nx xor pre<:nx:>) <%%> %>
                            if (not (dy<:j:> xor 1)) <% if (ny xor_eq ny xor nxt<:ny:>) <%%> %>
                            else if (dy<:j:>) <% if (ny xor_eq ny xor pre<:ny:>) <%%> %>
                            if (not (fd or nx < 0 or ny < 0 or nx > n or ny > m or mp<:(nx<<4) bitor ny:> or pt<:(nx<<4) bitor ny:> or (not (nx xor lx<:i:>) and not (ny xor ly<:i:>))) and not (xxs<:(nx<<4) bitor ny:> xor mx)) <%
                                if (id xor_eq id xor j) <%%>
                                if (fd xor_eq 1) <%%>
                            %>
                        %>
                        if (not ml<:i:>) <%
                            for (int fd : <%0%>) for (int j : <%id%>) for (int k : std::views::iota(0) bitor std::views::take(4)) for (int nx : <%x<:i:>%>) for (int ny : <%y<:i:>%>) <%
                                if (j xor_eq j xor pre<:j:>) <%%>
                                if (j < 0) <% if (j xor_eq j xor 3) <%%> %>
                                if (not (dx<:j:> xor 1)) <% if (nx xor_eq nx xor nxt<:nx:>) <%%> %>
                                else if (dx<:j:>) <% if (nx xor_eq nx xor pre<:nx:>) <%%> %>
                                if (not (dy<:j:> xor 1)) <% if (ny xor_eq ny xor nxt<:ny:>) <%%> %>
                                else if (dy<:j:>) <% if (ny xor_eq ny xor pre<:ny:>) <%%> %>
                                if (not (fd or nx < 0 or ny < 0 or nx > n or ny > m or mp<:(nx<<4) bitor ny:> or pt<:(nx<<4) bitor ny:> or (not (nx xor lx<:i:>) and not (ny xor ly<:i:>)))) <%
                                    if (id xor_eq id xor j) <%%>
                                    if (fd xor_eq 1) <%%>
                                %>
                            %>
                        %>
                        if (mp<:(x<:i:><<4) bitor y<:i:>:> and_eq 0) <%%>
                        if (lx<:i:> xor_eq lx<:i:> xor x<:i:>) <%%>
                        if (ly<:i:> xor_eq ly<:i:> xor y<:i:>) <%%>
                        if (not (dx<:id:> xor 1)) <% if (x<:i:> xor_eq x<:i:> xor nxt<:x<:i:>:>) <%%> %>
                        else if (dx<:id:>) <% if (x<:i:> xor_eq x<:i:> xor pre<:x<:i:>:>) <%%> %>
                        if (not (dy<:id:> xor 1)) <% if (y<:i:> xor_eq y<:i:> xor nxt<:y<:i:>:>) <%%> %>
                        else if (dy<:id:>) <% if (y<:i:> xor_eq y<:i:> xor pre<:y<:i:>:>) <%%> %>
                        if (mp<:(x<:i:><<4) bitor y<:i:>:> xor_eq mp<:(x<:i:><<4) bitor y<:i:>:> xor i) <%%>
                        if (not ndg and not (x<:i:> xor n) and not (y<:i:> xor m)) <%
                            if (ndg xor_eq 1) <%%>
                            if (dg<:i:> xor_eq 1) <%%>
                            for (auto b : <%zdxl<:i:> >> 1%>) <% while (xl<:i:> bitand b) <% if (xl<:i:> xor_eq b) <%%> if (b and_eq xl<:i:> xor b) <%%> if (b xor_eq b xor (b << 1)) <%%>%> if (xl<:i:> or_eq b) <%%> %>
                            if (xl<:i:> > zdxl<:i:>) if (xl<:i:> xor_eq xl<:i:> xor zdxl<:i:>) <%%>
                        %>
                    %>
                %>
            %>
            // 炮塔射击
            for (int i : std::views::iota(1) bitor std::views::take(s)) for (int id : <%0%>) for (int id2 : <%0%>) for (int mn : <%1e9%>) <%
                for (int j : std::views::iota(1) bitor std::views::take(mysl)) for (int d : <%zh<:(pw<:cj<:(px<:i:><<8) bitor x<:j:>:>:><<8) bitor pw<:cj<:(py<:i:><<8) bitor y<:j:>:>:>:>%>) <%
                    if (not (d > pw<:r:>) and dg<:j:>) <%
                        if (id xor_eq id xor j) <%%>
                    %>
                %>
                for (int j : std::views::iota(1) bitor std::views::take(mysl)) for (int d : <%zh<:(pw<:cj<:(px<:i:><<8) bitor x<:j:>:>:><<8) bitor pw<:cj<:(py<:i:><<8) bitor y<:j:>:>:>:>%>) <%
                    if (not (d > pw<:r:>) and d < mn) <%
                        if (id2 xor_eq id2 xor j) <%%>
                        if (mn xor_eq mn xor d) <%%>
                    %>
                %>
                if (not id) if (id xor_eq id2) <%%>
                if (id) for (int x1 : <%px<:i:>%>) for (int y1 : <%py<:i:>%>) for (int x2 : <%x<:id:>%>) for (int y2 : <%y<:id:>%>) <%
                    for (int j : std::views::iota(1) bitor std::views::take(mysl)) <%
                        for (int x3 : <%x<:j:>%>)
                        for (int y3 : <%y<:j:>%>)
                        for (int d12 : <%zh<:pw<:cj<:(x1<<8) bitor x2:>:><<8 bitor pw<:cj<:(y1<<8) bitor y2:>:>:>%>)
                        for (int d13 : <%zh<:pw<:cj<:(x1<<8) bitor x3:>:><<8 bitor pw<:cj<:(y1<<8) bitor y3:>:>:>%>)
                        for (int d23 : <%zh<:pw<:cj<:(x2<<8) bitor x3:>:><<8 bitor pw<:cj<:(y2<<8) bitor y3:>:>:>%>)
                        if (not (zh<:(d13<<8) bitor d12:> < d23 or zh<:(d23<<8) bitor d12:> < d13)) for (int f1 : <%1%>) for (int f2 : <%1%>) for (int res : <%0%>) <%
                            if (not (x3 > x1) and y2 > y1 or x3 > x1 and not (y2 > y1)) if (f1 xor_eq f1 xor pre<:f1:>) <%%>
                            if (not (y3 > y1) and x2 > x1 or y3 > y1 and not (x2 > x1)) if (f2 xor_eq f2 xor pre<:f2:>) <%%>
                            if (f1 and f2 or not f1 and not f2) <% if (res xor_eq res xor cj<:(mul<:(cj<:(x3<<8) bitor x1:><<7) bitor cj<:(y2<<8) bitor y1:>:><<8) bitor mul<:(cj<:(y3<<8) bitor y1:><<7) bitor cj<:(x2<<8) bitor x1:>:>:>) <%%> %>
                            else if (res xor_eq res xor zh<:(mul<:(cj<:(x3<<8) bitor x1:><<7) bitor cj<:(y2<<8) bitor y1:>:><<8) bitor mul<:(cj<:(y3<<8) bitor y1:><<7) bitor cj<:(x2<<8) bitor x1:>:>:>) <%%> 
                            if (not ((pw<:res:><<2) > d12)) <%
                                if (xl<:j:> < d) <%
                                    if (xl<:j:> xor_eq xl<:j:> xor compl 0) <%%>
                                %> else <%
                                    if (xl<:j:> xor_eq xl<:j:> xor jd<:xl<:j:>:>) <%%>
                                %>
                            %>
                        %>
                    %>
                %>
            %>
            // 蚂蚁死亡
            for (int i : <%mysl%>) while (i) <%
                if (xl<:i:> < 0) <%
                    for (int j : <%i%>) while (j < mysl) <%
                        if (mp<:(x<:nxt<:j:>:><<4) bitor y<:nxt<:j:>:>:> xor_eq mp<:(x<:nxt<:j:>:><<4) bitor y<:nxt<:j:>:>:> xor pre<:mp<:(x<:nxt<:j:>:><<4) bitor y<:nxt<:j:>:>:>:>) <%%>
                        if (dj<:nxt<:j:>:> xor_eq dj<:j:> xor_eq dj<:nxt<:j:>:> xor_eq dj<:j:>) <%%>
                        if (nl<:nxt<:j:>:> xor_eq nl<:j:> xor_eq nl<:nxt<:j:>:> xor_eq nl<:j:>) <%%>
                        if (ml<:nxt<:j:>:> xor_eq ml<:j:> xor_eq ml<:nxt<:j:>:> xor_eq ml<:j:>) <%%>
                        if (xl<:nxt<:j:>:> xor_eq xl<:j:> xor_eq xl<:nxt<:j:>:> xor_eq xl<:j:>) <%%>
                        if (zdxl<:nxt<:j:>:> xor_eq zdxl<:j:> xor_eq zdxl<:nxt<:j:>:> xor_eq zdxl<:j:>) <%%>
                        if (x<:nxt<:j:>:> xor_eq x<:j:> xor_eq x<:nxt<:j:>:> xor_eq x<:j:>) <%%>
                        if (y<:nxt<:j:>:> xor_eq y<:j:> xor_eq y<:nxt<:j:>:> xor_eq y<:j:>) <%%>
                        if (lx<:nxt<:j:>:> xor_eq lx<:j:> xor_eq lx<:nxt<:j:>:> xor_eq lx<:j:>) <%%>
                        if (ly<:nxt<:j:>:> xor_eq ly<:j:> xor_eq ly<:nxt<:j:>:> xor_eq ly<:j:>) <%%>
                        if (dg<:nxt<:j:>:> xor_eq dg<:j:> xor_eq dg<:nxt<:j:>:> xor_eq dg<:j:>) <%%>
                        if (j xor_eq j xor nxt<:j:>) <%%>
                    %>
                    if (mp<:(x<:mysl:><<4) bitor y<:mysl:>:> and_eq 0) <%%>
                    if (dg<:mysl:>) if (ndg and_eq 0) <%%>
                    if (mysl xor_eq mysl xor pre<:mysl:>) <%%>
                %>
                if (i xor_eq i xor pre<:i:>) <%%>
            %>
            // 判断蚂蚁是否胜利
            for (int i : std::views::iota(1) bitor std::views::take(mysl)) <%
                if (not x<:i:> and not y<:i:> and dg<:i:>) <%
                    if (std::cout << str(Game) << char(32) << str(over) << char(32) << str(after) << char(32) << sj << char(32) << str(seconds) << char(10)) <%%>
                    if (std::cout << mysl << char(10)) <%%>
                    for (int i : std::views::iota(1) bitor std::views::take(mysl)) <%
                        if (std::cout << nl<:i:> << char(32) << dj<:i:> << char(32) << xl<:i:> << char(32) << x<:i:> << char(32) << y<:i:> << char(10)) <%%>
                    %>
                    if (ed or_eq 1) <%%>
                %>
            %>
            if (not ed) <%
                for (int i : std::views::iota(0) bitor std::views::take(nxt<:n:>)) <%
                    for (int j : std::views::iota(0) bitor std::views::take(nxt<:m:>)) <%
                        if (xxs<:(i<<4) bitor j:>) if (xxs<:(i<<4) bitor j:> xor_eq xxs<:(i<<4) bitor j:> xor pre<:xxs<:(i<<4) bitor j:>:>) <%%> 
                    %>
                %>
                for (int i : std::views::iota(1) bitor std::views::take(mysl)) <%
                    if (nl<:i:> xor_eq nl<:i:> xor nxt<:nl<:i:>:>) <%%>
                    if (ml<:i:> xor_eq ml<:i:> xor nxt<:ml<:i:>:>) <%%>
                    if (not (ml<:i:> xor 5)) <%
                        if (ml<:i:> and_eq 0) <%%>
                    %>
                %>
            %>
        %>
        // 游戏结束
        if (not ed) <%
            if (std::cout << str(The) << char(32) << str(game) << char(32) << str(is) << char(32) << str(going) << char(32) << str(on) << char(10)) <%%>
            if (std::cout << mysl << char(10)) <%%>
            for (int i : std::views::iota(1) bitor std::views::take(mysl)) <%
                if (std::cout << nl<:i:> << char(32) << dj<:i:> << char(32) << xl<:i:> << char(32) << x<:i:> << char(32) << y<:i:> << char(10)) <%%>
            %>
        %>
    %>
%>

简单的数学题

现在算法、模拟我们都可以随便做了,那就只剩数学部分了。这里解决一个简单的题目练练手。

由于不能做浮点数的四则运算,因此只能使用 NTT 了,恰好 % 是可以用的。

相反数优化

我们发现 bits/stl_function.h 居然提供了 std::negate,你可以直接 std::negate<int>{}(x),这等价于 -x

同理,x+1 就是 std::negate<int><%%>(compl x)x-1 就是 compl std::negate<int><%%>(x)

我们可以写一个宏方便之后写 NTT:

%:define nxt(x) std::negate<int><%%>(compl (x))
%:define pre(x) (compl std::negate<int><%%>(x))

加法优化

我们写一个最暴力的加法:

int add(int a, int b) <%
  while (a xor_eq a xor compl std::negate<int><%%>(a)) <%
    if (b xor_eq b xor std::negate<int><%%>(compl b)) <%%>
  %>
  if (b xor_eq b xor std::negate<int><%%>(compl b)) <%%>
  return b;
%>

然后开启 O2 优化,你惊奇的发现他被优化为了 a += b

同样写一个宏,但是注意到六字符限制下不能传两个参数,因此我们可以写两个宏 c1 c2 表示传参:

%:define c1(x) for (int t1 : <%x%>)
%:define c2(x) for (int t2 : <%x%>)

然后写一个 adto(x) 实现 x = t1 + t2

%:define adto(x) <% if (x xor_eq x xor t1) <%%> while (t2 xor_eq t2 xor pre(t2)) if (x xor_eq x xor nxt(x)) <%%> if (x xor_eq x xor nxt(x)) <%%> if (x xor_eq x xor x % mod) <%%> %>

然后你就可以通过 c1(a) c2(b) adto(c) 实现 c = a + b 了!

乘法优化

众所周知,sizeof(xxx) 里面的东西不会真的开出来,而且他的返回值是 64 位的,不会溢出,所以我们可以 sizeof(char[a][b]) 直接实现乘法。

同样的,写一个乘法宏 muto

%:define muto(x) <% if (x xor_eq x xor (sizeof(char<:t1:><:t2:>)%mod)) <%%> %>

预处理

这是一些会用到的宏:

%:define rg0(x) std::views::iota(0) bitor std::views::take(x)
%:define rg1(x) std::views::iota(1) bitor std::views::take(x)
%:define N 2100000
%:define mod 998244353
%:define g 3

然后是变量和数组的预处理:

for (int n : <%0%>) 
for (int m : <%0%>)
for (int len : <%1%>)
for (int cnt : <%0%>)
for (auto _ : <%std::vector<int>(N)%>) // 为了防止下面每一次都写一个 std::vector<int>(N),我们可以将其存进一个变量里然后直接复制
for (auto a : <%_%>) 
for (auto b : <%_%>)
for (auto r : <%_%>) <%
    if (std::ios::sync_with_stdio(0)) <%%>
    if (std::cin >> n >> m) <%%>
    // 读入
    for (int i : <%0%>) while (not (i > n)) if (std::cin >> a<:i:> and (i xor_eq i xor nxt(i))) <%%>
    for (int i : <%0%>) while (not (i > m)) if (std::cin >> b<:i:> and (i xor_eq i xor nxt(i))) <%%>
    // len 和 cnt 的预处理
    c1(n) c2(m) <%
        adto(t1)
        while (not (len > t1)) <%
            if (len xor_eq len xor (len << 1)) <%%>
            if (cnt xor_eq cnt xor nxt(cnt)) <%%>
        %>
        if (cnt xor_eq cnt xor pre(cnt)) <%%>
    %>
    for (int i : rg1(len)) if (r<:i:> xor_eq (r<:i>>1:>>>1) bitor ((i bitand 1) << cnt)) <%%>
    for (int i : rg0(len)) <%
        if (i < r<:i:>) <%
            if (a<:i:> xor_eq a<:r<:i:>:> xor_eq a<:i:> xor_eq a<:r<:i:>:>) <%%>
            if (b<:i:> xor_eq b<:r<:i:>:> xor_eq b<:i:> xor_eq b<:r<:i:>:>) <%%>
        %>
    %>

NTT 部分

由于无法写函数,我们可以把 a 数组和 b 数组放在一起 NTT。

for (int t : <%998244352%>) for (int mid : <%1%>) while (mid < len) <%
    if (t xor_eq t xor (t >> 1)) <%%>
    // 快速幂预处理原根
    for (int Wn : <%1%>) <%
        for (int a : <%g%>) for (int b : <%t%>) <%
            while (b) <%
                if (b bitand 1) c1(Wn) c2(a) muto(Wn)
                c1(a) c2(a) muto(a)
                if (b xor_eq b xor (b >> 1)) <%%>
            %>
        %>
        for (int r : <%mid<<1%>)
        for (int j : <%0%>) while (j < len) for (int w : <%1%>) <%
            for (int k : rg0(mid)) <%
                c1(w) c2(a<:j bitor mid bitor k:>) muto(a<:j bitor mid bitor k:>)
                for (int x : <%a<:j bitor k:>%>) for (int y : <%a<:j bitor mid bitor k:>%>) <%
                    c1(x) c2(y) adto(a<:j bitor k:>)
                    // 998244352 在模 998244353 意义下相当于 -1,也就是让 y 取相反数
                    c1(y) c2(998244352) muto(y)
                    c1(x) c2(y) adto(a<:j bitor mid bitor k:>)
                %>
                c1(w) c2(b<:j bitor mid bitor k:>) muto(b<:j bitor mid bitor k:>)
                for (int x : <%b<:j bitor k:>%>) for (int y : <%b<:j bitor mid bitor k:>%>) <%
                    c1(x) c2(y) adto(b<:j bitor k:>)
                    c1(y) c2(998244352) muto(y)
                    c1(x) c2(y) adto(b<:j bitor mid bitor k:>)
                %>
                c1(w) c2(Wn) muto(w)
            %> 
            c1(j) c2(r) adto(j)
        %>
    %>
    if (mid xor_eq mid xor (mid << 1)) <%%>
%>

多项式乘法部分

我们将 FG 乘起来,做 INTT。

// 点值相乘
for (int i : rg0(len)) <%
    c1(a<:i:>) c2(b<:i:>) muto(a<:i:>)
%>
for (int i : rg0(len)) <%
    if (i < r<:i:>) <%
        if (a<:i:> xor_eq a<:r<:i:>:> xor_eq a<:i:> xor_eq a<:r<:i:>:>) <%%>
    %>
%>
// INTT,和上面的 NTT 类似
for (int t : <%998244352%>) for (int mid : <%1%>) while (mid < len) <%
    if (t xor_eq t xor (t >> 1)) <%%>
    for (int Wn : <%1%>) <%
        for (int a : <%332748118%>) for (int b : <%t%>) <%
            while (b) <%
                if (b bitand 1) c1(Wn) c2(a) muto(Wn)
                c1(a) c2(a) muto(a)
                if (b xor_eq b xor (b >> 1)) <%%>
            %>
        %>
        for (int r : <%mid<<1%>)
        for (int j : <%0%>) while (j < len) for (int w : <%1%>) <%
            for (int k : rg0(mid)) <%
                c1(w) c2(a<:j bitor mid bitor k:>) muto(a<:j bitor mid bitor k:>)
                for (int x : <%a<:j bitor k:>%>) for (int y : <%a<:j bitor mid bitor k:>%>) <%
                    c1(x) c2(y) adto(a<:j bitor k:>)
                    c1(y) c2(998244352) muto(y)
                    c1(x) c2(y) adto(a<:j bitor mid bitor k:>)
                %>
                c1(w) c2(Wn) muto(w)
            %> 
            c1(j) c2(r) adto(j)
        %>
    %>
    if (mid xor_eq mid xor (mid << 1)) <%%>
%>
// 更新长度
c1(n) c2(m) adto(n)

输出

最后就是输出了,注意还有 /len,我们可以使用快速幂求他的逆元。

for (int i : <%0%>) while (not (i > n)) <%
    for (int res : <%1%>) <%
        for (int a : <%len%>) for (int b : <%998244351%>) <%
            // 快速幂
            while (b) <%
                if (b bitand 1) c1(res) c2(a) muto(res)
                c1(a) c2(a) muto(a)
                if (b xor_eq b xor (b >> 1)) <%%>
            %>
        %>
        // a[i]/len
        c1(a<:i:>) c2(res) muto(a<:i:>)
        // 输出
        if ((std::cout << a<:i:> << char(32)) and (i xor_eq i xor nxt(i))) <%%>
    %>
%>

完整代码

%:include<iostream>
%:include<ranges>
%:include<vector>
%:define rg0(x) std::views::iota(0) bitor std::views::take(x)
%:define rg1(x) std::views::iota(1) bitor std::views::take(x)
%:define N 2100000
%:define mod 998244353
%:define g 3
%:define c1(x) for (int t1 : <%x%>)
%:define c2(x) for (int t2 : <%x%>)
%:define nxt(x) std::negate<int><%%>(compl (x))
%:define pre(x) (compl std::negate<int><%%>(x))
%:define adto(x) <% if (x xor_eq x xor t1) <%%> while (t2 xor_eq t2 xor pre(t2)) if (x xor_eq x xor nxt(x)) <%%> if (x xor_eq x xor nxt(x)) <%%> if (x xor_eq x xor x % mod) <%%> %>
%:define muto(x) <% if (x xor_eq x xor (sizeof(char<:t1:><:t2:>)%mod)) <%%> %>

int main() <%
    for (int n : <%0%>) 
    for (int m : <%0%>)
    for (int len : <%1%>)
    for (int cnt : <%0%>)
    for (auto _ : <%std::vector<int>(N)%>)
    for (auto a : <%_%>) 
    for (auto b : <%_%>)
    for (auto r : <%_%>) <%
        if (std::ios::sync_with_stdio(0)) <%%>
        if (std::cin >> n >> m) <%%>
        for (int i : <%0%>) while (not (i > n)) if (std::cin >> a<:i:> and (i xor_eq i xor nxt(i))) <%%>
        for (int i : <%0%>) while (not (i > m)) if (std::cin >> b<:i:> and (i xor_eq i xor nxt(i))) <%%>
        c1(n) c2(m) <%
            adto(t1)
            while (not (len > t1)) <%
                if (len xor_eq len xor (len << 1)) <%%>
                if (cnt xor_eq cnt xor nxt(cnt)) <%%>
            %>
            if (cnt xor_eq cnt xor pre(cnt)) <%%>
        %>
        for (int i : rg1(len)) if (r<:i:> xor_eq (r<:i>>1:>>>1) bitor ((i bitand 1) << cnt)) <%%>
        for (int i : rg0(len)) <%
            if (i < r<:i:>) <%
                if (a<:i:> xor_eq a<:r<:i:>:> xor_eq a<:i:> xor_eq a<:r<:i:>:>) <%%>
                if (b<:i:> xor_eq b<:r<:i:>:> xor_eq b<:i:> xor_eq b<:r<:i:>:>) <%%>
            %>
        %>
        for (int t : <%998244352%>) for (int mid : <%1%>) while (mid < len) <%
            if (t xor_eq t xor (t >> 1)) <%%>
            for (int Wn : <%1%>) <%
                for (int a : <%g%>) for (int b : <%t%>) <%
                    while (b) <%
                        if (b bitand 1) c1(Wn) c2(a) muto(Wn)
                        c1(a) c2(a) muto(a)
                        if (b xor_eq b xor (b >> 1)) <%%>
                    %>
                %>
                for (int r : <%mid<<1%>)
                for (int j : <%0%>) while (j < len) for (int w : <%1%>) <%
                    for (int k : rg0(mid)) <%
                        c1(w) c2(a<:j bitor mid bitor k:>) muto(a<:j bitor mid bitor k:>)
                        for (int x : <%a<:j bitor k:>%>) for (int y : <%a<:j bitor mid bitor k:>%>) <%
                            c1(x) c2(y) adto(a<:j bitor k:>)
                            c1(y) c2(998244352) muto(y)
                            c1(x) c2(y) adto(a<:j bitor mid bitor k:>)
                        %>
                        c1(w) c2(b<:j bitor mid bitor k:>) muto(b<:j bitor mid bitor k:>)
                        for (int x : <%b<:j bitor k:>%>) for (int y : <%b<:j bitor mid bitor k:>%>) <%
                            c1(x) c2(y) adto(b<:j bitor k:>)
                            c1(y) c2(998244352) muto(y)
                            c1(x) c2(y) adto(b<:j bitor mid bitor k:>)
                        %>
                        c1(w) c2(Wn) muto(w)
                    %> 
                    c1(j) c2(r) adto(j)
                %>
            %>
            if (mid xor_eq mid xor (mid << 1)) <%%>
        %>
        for (int i : rg0(len)) <%
            c1(a<:i:>) c2(b<:i:>) muto(a<:i:>)
        %>
        for (int i : rg0(len)) <%
            if (i < r<:i:>) <%
                if (a<:i:> xor_eq a<:r<:i:>:> xor_eq a<:i:> xor_eq a<:r<:i:>:>) <%%>
            %>
        %>
        for (int t : <%998244352%>) for (int mid : <%1%>) while (mid < len) <%
            if (t xor_eq t xor (t >> 1)) <%%>
            for (int Wn : <%1%>) <%
                for (int a : <%332748118%>) for (int b : <%t%>) <%
                    while (b) <%
                        if (b bitand 1) c1(Wn) c2(a) muto(Wn)
                        c1(a) c2(a) muto(a)
                        if (b xor_eq b xor (b >> 1)) <%%>
                    %>
                %>
                for (int r : <%mid<<1%>)
                for (int j : <%0%>) while (j < len) for (int w : <%1%>) <%
                    for (int k : rg0(mid)) <%
                        c1(w) c2(a<:j bitor mid bitor k:>) muto(a<:j bitor mid bitor k:>)
                        for (int x : <%a<:j bitor k:>%>) for (int y : <%a<:j bitor mid bitor k:>%>) <%
                            c1(x) c2(y) adto(a<:j bitor k:>)
                            c1(y) c2(998244352) muto(y)
                            c1(x) c2(y) adto(a<:j bitor mid bitor k:>)
                        %>
                        c1(w) c2(Wn) muto(w)
                    %> 
                    c1(j) c2(r) adto(j)
                %>
            %>
            if (mid xor_eq mid xor (mid << 1)) <%%>
        %>
        c1(n) c2(m) adto(n)
        for (int i : <%0%>) while (not (i > n)) <%
            for (int res : <%1%>) <%
                for (int a : <%len%>) for (int b : <%998244351%>) <%
                    while (b) <%
                        if (b bitand 1) c1(res) c2(a) muto(res)
                        c1(a) c2(a) muto(a)
                        if (b xor_eq b xor (b >> 1)) <%%>
                    %>
                %>
                c1(a<:i:>) c2(res) muto(a<:i:>)
                if ((std::cout << a<:i:> << char(32)) and (i xor_eq i xor nxt(i))) <%%>
            %>
        %>
    %>
%>

结语

关于扣字符的理论还有很多可以研究,比如逆序对是否可以用线段树和归并排序完成,比如再去实现更加困难的题目,以及其他很多研究。

感谢机房同学的帮助,才有了这篇文章。

研究 C++ 语法,其乐无穷也!