A

枚举长度 ll,那么有解的一个必要条件是 97ln122l97l\le n\le 122l,其中 9797122122 分别是 az 的 ASCII 码。

可以用 zzzzz...caaaaa 这种方式来构造,考虑把第一个字母从 a 变为 z,第二个字母从 a 变为 z,一直这样重复下去,显然这可以满足 97l122l97l\sim 122l 内任意的 nn

至多需要枚举 n/97\lfloor n/97\rfloor 次,因此复杂度为 O(n)O(n)

B

如果我们可以给所有距离 <d<d 的点连一条无向边,那么这就是一个二分图染色问题。

类比平面最近点对,令 D=d/2D=\lceil d/2\rceil,那么按照 (xi/D,yi/D,zi/D)(\lfloor x_i/D\rfloor, \lfloor y_i/D\rfloor, \lfloor z_i/D\rfloor) 给所有点分组。

同一组内最大距离为 32D<d\cfrac{\sqrt{3}}{2} D < d,所以每一组不能有超过三个点,否则无法二分图染色;其次,同一组内的点至多与周围 535^3 个组内的点距离 <d<d,所以我们可以 O(n)O(n) 给所有点对连边。

假设一个连通的二分图内有 aa 个白点,权值之积为 waw_abb 个黑点,权值之积为 wbw_b。那么 F(z)=waza+wbzbF(z)=w_az^a+w_bz^b

分治 NTT 把所有的 FF 乘起来即可,复杂度 O(nlog2n)O(n\log^2n)

C

对于两个人的情况,可以查看官方题解,这里主要会对调整一次后 “边数减少” 这个事情进行说明。

令有向边 iji\to j 存在当且仅当 wi(Si)<wi(Sj)w_i(S_i)<w_i(S_j),考虑增量构造,将 1m1\sim m 依次分配。

  1. 如果当前图内没有环,也就存在一个 00 入度的点,我们直接把当前物品分配给这个点。

  2. 否则,假设我们找到了一个简单环 p1p2pkp1p_1\to p_2\to \cdots \to p_k \to p_1,将它们的 Sp1,Sp2,,SpkS_{p_1},S_{p_2},\dots, S_{p_k} 调整为 Sp2,Sp3,,Sp1S_{p_2},S_{p_3},\dots, S_{p_1},那么所有人的 wi(Si)w_i(S_i) 都会增加。

    对于调整之前的所有边 iji\to j,我们将它们分为四类。

    • 如果 i,ji,j 都不在环上,那么这条边依旧存在。
    • 如果 ii 在环上,jj 不在环上,那么这条边可能存在,也可能不存在。
    • 如果 ii 不在环上,jj 在环上,那么这条边会向前循环移动一个位置。比如 ip3i\to p_3 变为 ip2i\to p_2ip1i\to p_1 变为 ipki\to p_k
    • 如果 i,ji,j 都在环上,那么这条边向前循环移动一个位置后,可能存在也可能不存在,但是不会产生自环。比如 p1p3p_1\to p_3 变为 p1p2p_1\to p_2,但是 w1(S1)w_1(S_1) 本身也变大了,这条边可能不存在;但是 p1p2p_1\to p_2 不会变成 p1p1p_1\to p_1

    反过来看,如果调整之后存在一条边 iji\to j,通过上面类似的分类讨论,它一定可以对应到调整前的一条边上。

    所以边数每次至少减少了 kk,我们反复调整直到这个图里没有环为止。

这样的话,我们对每次新增的集合询问 nn 个人对它的权值,恰好询问 nmnm 次。

每次新增边至多 n1n-1 条,每一条环边我们会以 O(n2)O(n^2) 的代价消掉,因此最终的复杂度 O(n3m)O(n^3m)

D

如果每次都可以重分配,假设有 WW 个工人,我们一定会让他们去 xix_iWW 大的工厂。

但是只有当一次添加工人操作可以重分配,剩下的时间并不能重分配。

我们考虑一次 w 操作后跟着若干个 f 为一组,假设这一组内的工厂为 y1,y2,,yky_1,y_2,\dots, y_k,之前的工厂为 x1,x2,,xmx_1,x_2,\dots, x_m,都是从大到小排序,并且有 WW 个工人。

假设我们规定有 ll 个工人最终被分配去这一组内的工厂,那么它们带来的利润是 j(kj+1)yj\sum_{j} (k-j+1)y_j,那么我们会把 (kj+1)yj(k-j+1)y_j 从大到小排序后选前 ll 大的,剩下的的 WlW-l 个工人会选择前 WlW-l 大的 xx

因此我们可以把 xx 离散化后存到树状数组中,每次枚举所有的 ll,树状数组二分找前 WlW-l 大的 xx 之和即可。

由于所有的 ll 之和是 O(n)O(n) 的,复杂度 O(nlogn)O(n\log n)

E

农民获胜有两种情况,要么是 AA 出完了所有的牌,要么是 BB 出完。

  1. 如果是 BB 出完了所有的牌,那么它只能在最后一次出牌时出 <pc<p_c 的单牌。

    如果 BB 只有一张这样的牌,那么我们的流程就是 AA 将主动权传递给 BB,然后 BB 出完自己所有的牌。

    传递主动权可以通过对子传递,也可以通过单张牌传递。如果通过单张牌传递,那么 BB 不能用 <pc<p_c 的单牌接受,除非 BB 只有这一张牌。

  2. 如果是 AA 出完了所有的牌,那么我们只需要考虑 AA 手中 <pc<p_c 的单牌。

    存在两种情况:

    1. BB 用一张 pc\ge p_c 的单牌接受,然后 AA 用一张更大的牌回收主动权,并且本轮结束。
    2. BB 用一张 pc\ge p_c 的单牌接受,然后 BB 出一个对子,并且 AA 回收主动权,并且本轮结束。

    虽然我没有办法严谨证明,但是 BB 如果不结束本回合的话,他手里的牌会更少,不会优于直接结束本轮。

这样用 set 维护,复杂度 O(nlogn)O(n\log n)

F

定义 dp(u,v)dp(u,v) 表示 uvu\to v 这个子树的 SG 值,每次 DFS 所有满足 dis(v,x)kdis(v, x) \le k 的点 xx 并把相连的所有子树的 SG 值异或起来就是当前局面的 SG 值。

这里可以类似换根 DP 的处理方式在 DFS 的过程中维护当前所有子树的异或,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int sg(int u, int f);

void dfs2(int u, int f, int d, vector<int>& out, int m = 0) {
for (int to: go[u]) {
if (to == f) continue;
m ^= sg(to, u);
}

out.push_back(m);
if (d >= k) return;
for (int to: go[u]) {
if (to == f) continue;
dfs2(to, u, d + 1, out, m ^ sg(to, u));
}
}

在一轮 DFS 结束后把 out 中的数求 MEX 就是当前子树的 SG,因此记忆化搜索即可,复杂度 O(n2)O(n^2)

G

对于 n,mn,m 其中之一是偶数的情况,可以构造出一条哈密顿回路;对于 n,mn,m 均为奇数的情况,并不能构造出来。

但是,我们并不是真的需要一条哈密顿回路,可以构造出来只是左上角一个点会变化的回路,我能构造出来的和官方题解一样,所以图我就不放了。

对于这个构造出来的两条变化的回路,它们只有一个点是不一样的,所以根据贪吃蛇的规则,这个蛇不可能在所有格子都被铺满之前咬到自己的尾巴。

构造出来之后就可以无脑让蛇头沿着图走了,复杂度 O((nm)2)O((nm)^2)

我在赛后让 Codex 造了一个可视化页面,有兴趣的读者可以看一下。

H

官方题解的括号匹配我没看懂,这里给出一个利用元素之和传递信息的做法。

假设 a1,a2,,aka_1,a_2,\dots,a_k 是给定的 SSb1,b2,,bnkb_1,b_2,\dots,b_{n-k}[n]S[n]\setminus S,其中 a,ba,b 均升序排序。

假设插入之后的升序数组为 a1,a2,,ai,bja_1,a_2,\dots, a_i,b_j,那么我们有 bj=i+jb_j=i+j,即 i=bjji=b_j-j

我们希望通过 i=1kai+bj\sum_{i=1}^k a_i + b_j 得到 bjjb_j-j,于是我们选择 j=nk(i=1kai)mod(nk)j=n-k-\left(\sum_{i=1}^k a_i\right)\bmod (n-k)

这样 i=1kai+bjbjj(modnk)\sum_{i=1}^k a_i+b_j \equiv b_j-j\pmod{n-k},又因为 nk>kn-k>k,所以 ii 可以被唯一还原出来。

复杂度 O(nlogn)O(n\log n),瓶颈在于排序。

I

本地 DFS 可以得知,由 060\sim 6 构成的长度为 66 的无序数组只有 30003000 个左右。

那么我们直接 30002×363000^2\times 36 打表即可,之后可以 O(1)O(1) 回答询问。

实测直接提交打表程序也是可行的。

J

对于每一条横线,它们的代价是相同的,因此我们可以通过调整法说明从 (0,0)(0,0) 到达 (ai,bj)(a_i,b_j) 只会走一条竖线,但是我们无法得知走哪一条竖线。

基于上面这个观察,我们可以给出一个显然的式子:

fij=min{minki{t0ai+tkbj},mink>i{2t0akt0ai+tkbj}}=t0ai+min{2t0ai+(minkitk)bj,mink>i{2t0ak+tkbj}}\begin{aligned} f_{ij}&=\min\left\{\min_{k\le i}\{t_0a_i+t_kb_j\},\min_{k>i}\{2t_0a_k-t_0a_i+t_kb_j\}\right\}\\ &=-t_0a_i+\min\left\{2t_0a_i+\left(\min_{k\le i}t_k\right)b_j,\min_{k>i}\{2t_0a_k+t_kb_j\}\right\} \end{aligned}

prei=minkitkpre_i=\min_{k\le i}t_kFi(x)=mink>i{2t0ak+tkx}F_i(x)=\min_{k>i}\{2t_0a_k+t_kx\},那么我们枚举 i=ni=ni=1i=1 的过程中维护 Fi(x)F_i(x) 这个凸包。由于 aia_i 是单调递减的,那么 yy 轴上的截距就是单调递减的,相当于我们每次用一条直线去更新这个凸包,这是可以直接用栈维护的。

具体地说,我们用线段树维护一个数组 C1,C2,,CmC_1,C_2,\dots,C_m,每次更新 ii 的时候从栈中获取到分界点,在分界线左边的我们进行 Cj2t0ai+tibjC_j\gets 2t_0a_i+t_ib_j

我们再维护一个答案 A1,A2,,AmA_1,A_2,\dots,A_m,每次需要额外对这个凸包用直线 2t0ai+preix2t_0a_i+pre_i x 找到一个分界点,左边进行 AjAj+2t0ai+preibjA_j\gets A_j+2t_0a_i+pre_i b_j,右边进行 AjAj+CjA_j\gets A_j+C_j

如果你无脑使用矩阵维护,是会 TLE 的,就算你循环展开了也是不行。

所以我们维护修改操作 (u,v,w,p,q,r)(u,v,w,p,q,r) 表示 (Aj,bj,Cj)(Aj+ubj+vCj+w,bj,pbj+qCj+r)(A_j,b_j,C_j) \gets (A_j+ub_j+vC_j+w, b_j,pb_j+qC_j+r),然后展一下式子看两个修改操作如何进行合并即可。

这样复杂度 O(nlogn+nlogm)O(n\log n+n\log m)

K

有加法是及其难做的,所以我们对这个式子变形得到 (ak)(bk)k2(modn)(a-k)(b-k)\equiv k^2\pmod n

在模 nn 意义下枚举所有的 ak,bka-k,b-k 等价于枚举所有的 a,ba,b,因此式子可以被化简:

f(n,k)=a=0n1b=0n1[abk2(modn)]=a=0n1b=0n1[(a,n)k2][a(a,n)bk2(a,n)(modn(a,n))]=a=0n1[(a,n)k2](a,n)\begin{aligned} f(n,k)&=\sum_{a=0}^{n-1}\sum_{b=0}^{n-1}[ab\equiv k^2\pmod n]\\ &=\sum_{a=0}^{n-1}\sum_{b=0}^{n-1}[(a,n)\mid k^2][\frac{a}{(a,n)}b\equiv \frac{k^2}{(a,n)}\pmod{\frac{n}{(a,n)}}]\\ &=\sum_{a=0}^{n-1}[(a,n)\mid k^2](a,n) \end{aligned}

于是就有:

k=0mf(n,k)=k=0ma=0n1(a,n)[(a,n)k2]=gng(k=0m[gk2])(a=0n1[(a,n)=g])=gng(k=0m[gk2])(a=1n[(a,n)=g])=gng(k=0m[gk2])(a=1n/g[(a,ng)=1])=gng(k=0m[gk2])φ(ng)\begin{aligned} \sum_{k=0}^m f(n,k)&=\sum_{k=0}^{m}\sum_{a=0}^{n-1}(a,n)[(a,n)\mid k^2]\\ &=\sum_{g\mid n}g\left(\sum_{k=0}^{m}[g\mid k^2]\right)\left(\sum_{a=0}^{n-1} [(a,n)=g]\right)\\ &=\sum_{g\mid n}g\left(\sum_{k=0}^{m}[g\mid k^2]\right)\left(\sum_{a=1}^{n} [(a,n)=g]\right)\\ &=\sum_{g\mid n}g\left(\sum_{k=0}^{m}[g\mid k^2]\right)\left(\sum_{a=1}^{n/g} \left[\left(a,\frac{n}{g}\right)=1\right]\right)\\ &=\sum_{g\mid n}g\left(\sum_{k=0}^{m}[g\mid k^2]\right) \varphi\left(\frac{n}{g}\right) \end{aligned}

其中 gk2g\mid k^2 我们可以通过质因数分解来看:枚举所有的质数 pp,那么 gk2g\mid k^2 当且仅当 Vp(g)2Vp(k)V_p(g)\le 2V_p(k),这等价于 12Vp(g)Vp(k)\lceil\cfrac{1}{2}V_p(g)\rceil\le V_p(k),于是我们枚举 gg 的时候算出 u(g)=pp12Vp(g)u(g)=\prod_p p^{\lceil\frac{1}{2}V_p(g)\rceil},那么答案可以进一步写为 gngφ(n/g)(m/u(g)+1)\sum_{g\mid n}g\varphi(n/g)(\lfloor m/u(g)\rfloor + 1)

直接试除法枚举因子即可,复杂度 O(n)O(\sqrt n)

L

viv_i 从小到大排序后,设 dpijdp_{ij} 表示前 ii 个装备花 jj 个硬币可以达到的期望的最大值。

接下来枚举选或不选,如果选择,那么将有 pi100\cfrac{p_i}{100} 的概率为 viv_i(1pi100)\left(1-\cfrac{p_i}{100}\right) 的概率为 dpi1,jwidp_{i-1,j-w_i},能这么转移的原因是前面的式子展开会形成相同的子结构。

类似 0101 背包转移即可,可以滚动数组压掉一维,复杂度 O(nm)O(nm)

M

枚举每一条线段,再枚举所有的展品,对于每一个展品我们处理出进入和退出的点,扫描线即可,复杂度 O(nm)O(nm)