UOJ随做
since 2023-05-06 16:12.
怎么都做过 uoj Round。/kk/kk/kk
只收录 UOJ 自己的题目,一些官方比赛题就算了。部分 bzoj 等处收录的题目也放上来。
没写题解不意味着没做,有的忘了写或者太草率了就算了。
部分前言删了。
【UER #1】DZY Loves Graph
题解
操作树一定形如一个毛毛虫。
考虑可撤销并查集维护联通块。
对于操作树上主干边暴力进行修改操作。
对于非主干边,可以只计算出答案。
加一条边可以使用并查集查询,删若干边的答案可以直接调之前某个版本的答案。
总复杂度 \(O(n+q\log n)\)。
【UR #1】缩进优化
题解
考虑枚举每个 \(x\) 计算答案。
假设值域为 \(v\),我们只用知道若干区间内的总和及带权和即可。
使用前缀和即可维护。
总复杂度 \(O(n+v\log v)\)。
【UR #1】外星人
题解
先排序,然后考虑有效的数一定单调减,我们在这些位置决策。
假设 \(a_1\ge a_2\ge a_3\ge\dots\ge a_n\)。
假设 \(f_{i,v}\) 表示考虑到第 \(i\) 项,模后值为 \(v\) 的方案数。
特别的,\(f_{0,v}=[v=x]\)。
显然
于是直接前缀和优化 dp 就是 \(O(nv)\) 的了。
【UR #2】跳蚤公路
题解
upd:这个做法假了。
注意到发财等价于路径上存在负权环。
只用计算每个源点可能到达的点往自己在 \(x\) 在什么范围时可能有负权环,最后把其所能到达的点更新一下即可。
我们可以把每个 SCC 拆开来考虑。对每个 SCC 设其中一个点 \(s\) 作为源点即可,容易发现此时不存在负环等价于不存在经过 \(s\) 的负环。
设 \(f(p,j)\) 为从 \(s\) 点到 \(p\) 点经过 \(j\) 个 \(x\) 的情况下剩余部分的最小代价。
如果 \(f(s,0)=-\infty\),显然始终存在负环。
否则如果 \(f(s,0)=0\),假设 \(f(s,a)\) 与 \(f(s,b)\) 两项将导致 \(\mathbb R\) 上 \(x\) 解集为空(\(a<0<b\)),则有 \(\min\{f(s,a)+ax,f(s,b)+bx\}<0,\forall x\in\mathbb R\),也即 \(\frac{f(s,b)}{b}<\frac{f(s,a)}{a}\),从而 \(bf(s,a)+(-a)f(s,b)<0\),于是 \(f(s,0)=-\infty\),矛盾。
因此 \(\mathbb R\) 上必定存在一组合法的 \(x\)。容易发现,此时 \(x\) 应当满足
考虑怎么快速计算出 \(f(s,j)\)。
考虑用 SPFA 松弛,如果计算过程中出现任一恒负环就无解。
否则 SPFA 可以在 \(O(n^3m)\) 内出解:分层图边数 \(O(nm)\),点数 \(O(n^2)\)。不过我写了如果进队 \(8n\) 次就直接判无解,这样就是 \(O(n^2m)\) 的了。
垂死病中惊坐起,这个复杂度假的!
我们大力猜测出题人没卡,然后大力写就是了。
【UR #2】树上GCD
题解
我们考虑分开 \(u\) 是 \(v\) 的祖先的贡献,和不是祖先的贡献。
对于 \(u\) 是 \(v\) 祖先的部分,我们可以在 \(v\) 处统计合法的 \(\operatorname{dist}(u,v)\),显然是 \(1\sim\operatorname{dep}(v)\),差分即可得到每种方法的数目。(认为根节点深度为 \(0\))
对于 \(u\) 不是 \(v\) 祖先的部分,我们考虑容斥。
考虑对每个 \(g\) 计算有多少点对 \(u,v\) 满足 \(g|\operatorname{dist}(u,r),g|\operatorname{dist}(v,r)\),其中 \(r=\operatorname{lca}(u,v)\neq u,u<v\)。
考虑对 \(g>B\) 和 \(g\le B\) 讨论。
对于 \(g>B\) 的部分,我们考虑长剖,在 \(r\) 处统计 \(g\) 的贡献。
在合并一个短段时,暴力加上长段中其对应的贡献。
容易发现只在短段长度 \(>B\) 时才会统计,因此最多统计 \(n/B\) 次,枚举的 \(g\) 的总数目不超过 \(n\),于是总复杂度即为 \(O(n^2/B)\)。
对于 \(g\le B\) 的部分,我们考虑对每个 \(g\) 暴力枚举答案,则我们可以对元素按模 \(g\) 余数的高度分类,进行 dp 即可。直接做单轮是可以做到 \(O(n)\) 的,故该部分总复杂度 \(O(nB)\)。
容斥的部分复杂度可以忽略不计,取 \(B=\sqrt n\),总复杂度 \(O(n\sqrt n)\)。
实测 \(B\) 比较小的时候这个比较快。
考虑如何卡满这个复杂度。
考虑一条长度为 \(n/2\) 的链,并且在根节点处挂 \(n/4B\) 个长为 \(2B\) 的链。那么容易发现每次合并的复杂度是 \(O(n)\) 的。
这样就卡满了 \(O(n^2/B)\)。
【UR #3】铀仓库
题解
Fact 1:任意一种选法方案的最小时间是到起点距离和的 \(2\) 倍。
Fact 2:任意一种最优解均可以从某个已有的位置开始,向左右挑一个近的扩展,来得到。
我们枚举起点,然后二分套二分,即为 \(O(n\log n\log v)\)。
考虑怎么优化。
注意到当起点单调增时,我们总可以令最优的最右端点不减,尺取即可解决。对左右暴力扩展即可。
【UR #3】链式反应
题解
简单 GF。
假设答案的 EGF 为 \(g\),光子选法的 EGF 为 \(f\),则
写一个在线卷积即可解决。
即,设 \(h=g^2/2\),则有
从而
直接同时处理就好了。总复杂度 \(O(n\log^2n)\)。
【UR #4】元旦激光炮
题解
肯定是卡二分次数,起码优化到 \(O(\log n)\),关键是怎么卡。
考虑到我们其实每次查询 \(3\) 个位置 \(u,v,w\),如果有 \(u+v+w=k\),则我们可以找到其中最大、最小的数,答案显然在这之间,从而压缩了这两者的上下界。
当对于一个数来说其选法上下界确定时,我们就转化成了只剩下 \(2\) 项的子问题。
对于只有 \(2\) 项的子问题,我们二分其中一个就做完了。
考虑原问题中怎么快速把至少一个缩到紧界。
假设现在上界 \(r_1,r_2,r_3\),下界 \(\ge1\),要求 \(k\)。
显然不妨 \(r_1\le r_2\le r_3\le k\le r_1+r_2+r_3\)。
考虑取三个数大致在 \(r_1k/(r_1+r_2+r_3),r_2k/(r_1+r_2+r_3),r_3k/(r_1+r_2+r_3)\) 的附近。那么必然有一项下界抬升 \(k/(r_1+r_2+r_3)\),一项上界降低 \(1-k/(r_1+r_2+r_3)\),于是至少有一个区间长度减半。
这样在 \(3\log\) 轮后就有一个数上下界固定了。
这样的总查询次数看上去是 \(11\log\) 的。
注意到整个过程是一体的,因此总次数不会超过 \(9\log\) 级别。
我们猜测实际次数跑不满,或者可以分析出更紧的界。
嗯做就是了。
乱写一通就过了。
【UR #5】怎样提高智商
题解
手玩一下。
A 0 0 0 0
A 0 0 0 0
A 0 0 0 0
A 0 0 0 0
A 0 0 0 0
A 0 0 0 0
似乎都是
A 0 0 0 0
A 0 0 0 0
...
A 0 0 0 0
?
此时答案即为 \(4\times3^{n-1}\)。
我们猜这是最优的。
然后就过了。
【UR #5】怎样更有力气
题解
显然就是求最小生成树,其中
考虑 Kruskal,我们从小到大考虑,每次把当前链上所有不同的图上联通块能合并的都合并上。容易发现两个联通块不能直接连接当且仅当他们两两间均不可联通。
直接做是没法做的,我们不妨先考虑 \(p=0\) 的情况,显然此时我们只用加树边,从大到小枚举方案,树剖维护链染色即可。
对于 \(p>0\) 的情况,仍然考虑从大到小染色替换,把树边能染的都染了,不能染的树边会把链分成若干段,剩下的这些链之间看看互相能不能染,把链之间“不能相连”的边找出,然后 dfs 即可知道剩下这些链直接互相连的方法,把那些边单独提出即可。
最后提取树边和非树边信息再做一次 Kruskal 即可。
总复杂度 2log,容易通过。常数瓶颈在 ODT 维护染色上。(不过如果写 Splay 复杂度就是 1log 的了)
考虑怎么小常数地优化这一块。
注意到我们是染色之后最后查询全局,我们可以把染色的部分离线下来,dfs 一遍整颗树,然后拿一个可并可删堆维护一下染色即可。
【UR #5】怎样跑得更快
题解
看到 \(\gcd/\operatorname{lcm}\) 的等式,考虑反演。
设 \(y_j=j^dx_j\),\(a_i=b_i/i^d\),\(s=c-d\),则有
考虑设
则
从而
设 \(S_d=h_d\sum_{d|j}y_j\),我们有
从而 \(S_d\) 易解,于是就可以推出
从而可以解出 \(y\)。
如果 \(S_d\neq0\land h_d=0\),则无解。
朴素实现是 \(O(n\log n)\) 的。使用狄利克雷前缀和即可做到单轮 \(O(n\log\log n)\),不过没啥必要。
新年的巧克力棒
题解
答案显然是 \(n-\operatorname{popcount}(n)\)。证明容易归纳。
然后就做完了。
新年的毒瘤
题解
首先由于合法等价于删掉后是一棵树,因此也就等价于删掉后 \(m=n-1\) 且图联通。
前一条可以使用当前节点的度数判,后一条则等价于当前点不是割点,直接做即可。
总复杂度 \(O(n)\)。
需要特判 \(m=n-2\) 的情况。
新年的桌游
题解
称四种牌分别为 \(\tt A\),\(\tt B\),\(\tt C\),\(\tt D\)。
双方的数目分别称为 \((a/b/c/d)_{0/1}\)。
如果 \(c_0>a_1\lor(a_0>0\land b_1=0)\),显然先手胜。
否则先手肯定把 \(c_0\) 先用完,使 \(a_1\leftarrow a_1-c_0\),\(c_0\leftarrow0\),然后看看如果 \(a_0\ge a_1\land d_0>0\),则先手胜。
否则看看对手是否能在下一轮直接弄死自己,如果能就输了。
否则,再使 \(a_0\leftarrow a_0-c_1\),\(c_1\leftarrow0\),这样接下来就不用考虑 \(\tt C\) 的影响了。
接着看看先手能不能出 \(\tt A\)。
如果 \(d_0=d_1=0\),显然双方会保持出 \(\tt A\) 直到一方被创死或者无法移动。
如果 \(d_0>0\land d_1=0\),先看看按刚刚的策略谁胜,再看看如果自己会输那么有没有 \(a_1-b_0\le a_0\),如果有就平局。因为显然有 \(b_1\ge a_0\lor b_0<b_1\),所以不能借机反杀。
如果 \(d_0=0\land d_1>0\),先看看先手第一步出 \(\tt A\) 的结果,然后看不出的结果,显然先手会取其中较好的结果。
这里不会有 \(d_1>0\land d_2>0\) 的情况,否则必然会在前两轮中结束。
这样就做完了。
新年的QAQ
题解
比较简单的题目!
考虑计算一个东西的时候计算两次,再计算其差值,然后如果差值非 \(0\) 则重算。
这个东西容易实现。
这样每种运算均可以做到比较高的正确率,直接做就好了。
输出大概长这样:
input n
input m
a = 1
b = 0
c = a + b
d = a + b
e = c - d
if e goto 5
f = c % m
g = c % m
h = f - g
if h goto 9
i = n - 1
j = n - 1
k = i - j
if k goto 13
a = b
b = f
n = i
if n goto 5
output b
【UR #6】破解密码
题解
容易发现
如果
则
否则,我们有
因此随意构造使 \(h_0\) 处合法即可。直接取模升位即可找到一组解。
【UR #6】智商锁
题解
hhz 其实以前和我们讲过这题。。。
考虑到这种题目一眼就不可做,于是就考虑通过一些人类智慧的乱搞解决。
首先一张图的生成树个数可以用矩阵树定理算出。
考虑先生成大量点数比较少的图,计算出其生成树个数。
然后用一条链把这些图串起来,这样方案数就是各部分的乘积。
根据当初 hhz 给的介绍,我们暴力随出 \(100000\) 张点数不超过 \(12\) 的联通图,然后每组询问把若干图直接拼在一起即可。。。
问题是怎么拼,其实每次随一个拼上直到找到为止,找不到就重随一个就行了233。
特判掉 \(k=0\) 就好了。
A+B Problem
题解
考虑大力跑流。
我们考虑构造一个最小割模型,共 \(3n+2\) 个点,\(S\) 与左部点连边 \(b\),右部点与 \(T\) 连边 \(w\),左右部点直接对应用 \(+\infty\) 相连,左部点往中部点连边权 \(p\),中部点和可能影响之的右部点用 \(+\infty\) 相连。
这样答案即为 \(\sum b+\sum w-c\),其中 \(c\) 为最小割大小。
直接做边数是 \(O(n^2)\) 的,按 uoj 的数据强度肯定是过不去的。
所以直接上主席树优化建图,即可做到 \(O(n\log n)\) 个点,\(O(n\log n)\) 条边,应该就能松过去了。
最好先进行值域离散化。
然后上面这种做法可能会导致某项两侧均被割掉从而答案错误,所以考虑怎么办。
考虑初始给 \(b,w\) 均加上一个极大数 \(A=300000\),使得一但割掉 \(n+1\) 个颜色就会带来过大的代价,不如直接选择,从而保证正确性。
【UR #7】水题生成器
题解
我们考虑假设已经解决了 \((n-1,\lfloor\frac{m}{n}\rfloor)\) 的问题,要解决 \((n,m)\) 的问题。
首先我们把 \(\lfloor\frac{m}{n}\rfloor\) 的答案全部乘 \(n\),变成 \(n\lfloor\frac{m}{n}\rfloor\) 的答案。
然后如果 \(m\neq n\lfloor\frac{m}{n}\rfloor\),我们再加入一项 \(m-n\lfloor\frac{m}{n}\rfloor\)。
这样就用 \(n-1\) 解决了 \(n\)。
而对于 \(n=1\) 的部分,容易直接计算。
这个做法容易写成循环的形式,进而做到 \(O(n)\)。
【UR #7】水题走四方
题解
注意到两个人中比较高的那个不可能更高了,因此我们对其设状态。
设 \(f_p\) 为子树中叶子节点的个数。
设 \(g_p\) 为子树中一人在根节点不动,一人从根开始在子树内游走的最小答案。
设 \(h_p\) 为子树中两人从根开始的最小答案。
答案即为 \(h_1\)。
我们设 \(d_{p,0/1}\) 为子树中最深、次深节点距自己的距离,且要求来自不同子树。这个容易 dp 维护。
从而
这样就可以 \(O(n^2)\) 转移了。
考虑优化,我们不妨规定当前转移总满足 \(\operatorname{dist}(p,q)\le d_{p,1}\),于是就有代价形如
的形式。容易发现这样子可以取到所有最优方案。
对于快速找到所有合法节点并更新的复杂度,使用长剖最多跳根号条重链的结论即可以分析出为 \(O(n\sqrt n)\)。
我们的目标是找到最大的 \(g_q+f_q\operatorname{dist}(p,q)-h_q\) 使得 \(\operatorname{dist}(p,q)\le d_{p,1}\)。
容易发现,这种贡献转移可以写作
注意到我们只用维护 \(g_p-h_p\) 的转移,如果用 \(w=g-h\) 改写,则应当形如
问题仅在于优化这个 \(w_p\) 的计算。
注意到只用求出 \(w_1\),于是可以改写成自顶向下的 dp。
设 \(r_p\) 为从 \(p\) 开始,通过 \(w\) 的转移,来传递到根的最大贡献,则在 dp 时可以这么考虑:
我们注意到 \(\operatorname{dist}(q,p)\) 可以被认为是 \(q\sim p\) 的路径上除了 \(q\) 以外的点的数目,因此可被认为是将一段路径上所有点的权值均用 \(f_p\) 表示。
由于 \(f\) 具有子树包含单调性,所以最优的 \(q\) 一定选择为离自己最近的 \(\deg>1\) 且合法的节点。容易发现这样子的方案一定不劣。(如果自己非要选更高的 \(q\),我们发现这个较低的 \(q\) 也一定可以选择用其更新,从而更优)
当递归到一个 \(\deg>1\) 的节点时,我们可以开一个单调栈来进行压栈。
弹栈时我们可以暴力二分出应当在何处弹单调栈,查询时亦可二分。由于普通二分常数太大,所以其实更建议倍增。
使用可回退化数据结构即可做到 \(O(n\log n)\),常数超级小,容易通过。
mx的组合数
题解
myy 好厉害!不过这种技巧放到现在可能就已经家喻户晓了(x
一道类似的题目:bzoj 2629 binomial。
基本原理是,注意到我们有 Lucas 定理,我们可以把组合数拆进制,转化成数位 dp 问题。
问题转化为进行 \(O(\log_pv)\) 轮两个长为 \(p\) 的数组的下标乘法卷积和逐点加法。
逐点加法容易做到 \(O(p)\),关键问题在于乘法卷积。
注意到 \(p\) 是质数,因此我们直接找出原根,然后把除了 \(0\) 位置之外的数全部用离散对数投影到 \([0,p-1)\) 上,转化成普通卷积,NTT 即可维护。
忽略掉找原根部分的复杂度,总复杂度 \(O(p\log v)\),足以通过此题。
mx的仙人掌
题解
显然不弱于 bzoj2125 最短路。
先建出圆方树,圆方边按 bzoj2125 的方法建出来,这样两个圆点的最短路可以按 LCA 直接分类计算。
然后单组询问的时候,由于总点数被限制了,不难想到建立虚树。
建出虚树后在虚树上直接换根 dp 即可找出从每个子树到当前点的最长路,总复杂度 \(O(n\log n)\),可以通过。
注意方点换根时需要一个单调队列。
【UER #2】手机的生产
题解
这个我熟!
容易发现就是统计所有合法计算式数目,使得其满足短路原理。(每个位置分三种状态:未计算 / \(0\) / \(1\))
对于由 \(n-1\) 个 &&
组成的计算式,其要么全是 \(1\),返回 \(1\);要么前一部分是 \(1\),中间一个 \(0\),后面未计算,返回 \(0\)。
对于由若干个 &&
计算式和 ||
组成的计算式,要么每个子式都返回 \(0\),要么前若干个返回 \(0\),中间一个返回 \(1\),后面的不计算。
这样,假设共有 \(m\) 个子式,每个子式有 \(a_j\) 个运算数,则答案即为
容易做到 \(O(m)\)。
【UER #2】信息的交换
题解
这个题目很有趣!
注意到这个其实就是 tarjan 的生成森林,并且把每颗树的出栈序都循环位移了一下。于是我们提取出每个置换环单独处理,这样就得到了每个联通块的出栈序。
这样,每个节点的父亲可以是下一项,也可以是下一项的祖先(如果兄弟大于自己)。返祖边在祖先的该方向儿子节点小于自己时可以加。容易发现拿也是一个祖先,因此只有到根为止(不包括根)小于自己的节点其父亲可以和自己连返祖边。
注意到一个子树必然是一个区间,直接区间 dp 即可。
设 \(f_{l,r}\) 为 \([l,r)\) 区间内的节点构成子树,且计算了返祖边贡献的方案数;设 \(g_{l,r}\) 为 \([l,r)\) 区间内的节点构成子树,且计算了返祖边贡献,且可以再往前加一个子树的方案数。容易列出区间 dp 的转移。
总复杂度 \(O(n^3)\),常数很小。
【UER #2】谣言的传播
题解
容易发现就是基环内向树上的路径。考虑构造方案让答案最小、最大。
最小解,我们先把树点全取父亲(如果能取),然后把环点全取父亲(如果能取),然后剩下点随便交替取(只要不取自己)。容易发现这样是最小的。
最大解就是深度和,考虑构造使得一个子树其差一个节点没取外面的点,且根节点没被取,容易加入一个子树时更新信息。在环上交错取即可。这样就取满了。
总复杂度 \(O(n)\)。
【UR #8】赴京赶考
题解
注意到行列对于移动时是否相同的贡献是独立的,分别求出最小值。
在环上两个方向分别对应一种走法,取 \(\min\) 即可。
预处理前缀和,复杂度 \(O(n+m+q)\)。
【UR #8】决战圆锥曲线
题解
完全没思路,看了题解。
大概就是,只用注意到,如果有一个 \(y_i\le y_j\land i<j\) 的存在,那前面的 \(i\) 对答案一定没有贡献。
然后使用类似于笛卡尔树的分析,期望只会有 \(\log\) 个合法元素,具体就是从左往右依次加入的单调栈。
既然是单调栈,考虑直接上记录区间内最大元素,每次询问时直接往某个会出现答案的子树递归。
由于有 \(2\) 操作,还应记录最小元素。
单次期望复杂度修改 \(O(\log n)\),查询 \(O(\log^2n)\)。
【UR #9】电路手动分析
题解
考虑 \(1\le a\le nm\) 个节点间已有的连边数目最多能有多少。
容易发现一个上界:\(2a\)。因为横的不多于 \(a\),竖的不多于 \(a\)。
所以还要连的边数是 \(a^2/2+O(a)\) 级别的。
因此我们的答案大概是 \(\sqrt{2r}+O(1)\) 级别的。
考虑二分答案 check 一个 \(a\) 对应的最多连边数目,故有 \(a=O(\sqrt r)\)。考虑怎么 check。
简单来说,我们注意到最优解一定可以形如一个矩形接上顶部若干个点,我们设宽上有 \(x\) 个点,则另一个方向上共有 \(\lceil\frac ax\rceil\) 个点,总边数为 \(2a-x-\lceil\frac ax\rceil\) 的。对行列边拆开分析容易发现这样最优。
注意到 \(x\) 取到 \(\sqrt a\) 附近时最优,直接暴力枚举一下即可;需要注意的是,我们总应有 \(x\le n\land\lceil\frac ax\rceil\le m\) 或者 \(x\le m\land\lceil\frac ax\rceil\le n\),把边界情况也扫一下就好了。
如果不想动脑,也可以直接数论分块枚举。
【UR #9】App 管理器
题解
做法假了,贺题解。
注意到就是定向使得最终为强连通分量。
大概做法是,把还未定向的边视作双向边,则除了当前考虑的边外,剩下的边一定存在方案使得两个被当前边连接的点中一个可以到达另一个。
直接把还不能到达的方向的边连上即可;否则随便连一条边即可。
【UER #3】开学前的作文
题解
考虑分类讨论。不妨 \(n\le m\)。
我们认为起点是 \((0,0)\),终点是 \((n,m)\)。
如果 \(n=0\),如果 \(m\le1\),答案为 \(m\),否则答案为 \(\lceil m/2\rceil+1\)。
否则,如果 \(n=m\),显然即为 \(n+1\)。
否则,答案即为 \(n+2+\lfloor(m-n)/2\rfloor\)。
然后就完了。
【UER #3】开学前的日历
题解
题目里的 \((u+i,v-i+j)\) 比较混乱邪恶,我们考虑把各行依次平移,使得修改的位置变为 \((u+i,u+v+j)\)。
先考虑 \(k=0\) 怎么做。
注意到
这样只用在 \((u,u+v)\) 处加 \(1\),每位分别向其右方和右下方作贡献即可。
当 \(k\ge0\) 时,由于只有 \(j\ge k\) 可以被贡献,我们考虑在 \((u,u+v+k)(u+1,u+v+k)(u+2,u+v+k)\dots(u+k,u+v+k)\) 处依次加上对应组合数的贡献即可。
考虑怎么实现这种效果。
考虑对每个 \(k\) 分别处理,在 \((u,u+v+k)\) 处加 \(1\),并考虑最后在计算出各部分系数 \(a_{k,u,v}\)。
那么最终一个位置 \((u,v)\) 被贡献的系数将是 \(\sum_k\sum_{j=0}^k\binom kja_{k,u,v-j}\)。
该部分直接暴力计算是 \(O(n^4)\) 的(认为 \(n,m\) 同阶),不优。
注意到,由于 \(\binom{k}{j}=\binom{k-1}{j-1}+\binom{k-1}{j}\),我们可以把 \(a_{k,u,v}\) 的贡献再移到 \(a_{k-1,u,v}\) 和 \(a_{k-1,u,v+1}\) 处,这样最后的 \(a_{0,u,v}\) 即是答案。
总复杂度 \(O(n^3+q)\)。
【UER #3】开学前的涂鸦
题解
注意到 \(m-n\le k-1\),考虑使用广义串并联图方法。
我们可以反复删割边(或者删一度点),缩二度点,叠合重边;每条边边权定义为左右分裂的方案数和将左右联通的方案数 \((u,v)\)。
当删掉割边时,对答案带来将左右直接联通的贡献,并裂开左右两侧,转成子问题;如果是删一度点,则只用考虑一侧子问题。
当缩二度点时,\((u',v')\leftarrow(u_1v_2+u_2v_1,v_1v_2)\)。
当叠合重边时,\((u',v')\leftarrow(u_1u_2,u_1v_2+u_2v_1+v_1v_2)\)。
反复操作直到图上没有割边(或者一度点)且无法缩二度点、叠合重边。
此时图上节点数会很少,显然不会多于 \(2k-2\),直接状压 dp 即可。
即,设 \(f_S\) 为 \(S\) 联通的方案数,\(g_S\) 为 \(S\) 的总选法数,容易有 \(g_S=\sum_{T\subseteq S,a\in T}f_Tg_{S-T}\prod_{x\in T,y\in S-T}v_{x,y}\),而 \(a\) 为 \(T\) 中的某个元素。
然后嗯上半半在线卷积就做完了。
简单来说,就是令 \((u,v)\leftarrow(u/v,1)\),且答案乘 \(v\);对于 \(v=0\) 的边,我们把两侧暴力缩点即可。
这样就变成了
钦定 \(a=0\),使用半半在线卷积即可维护。
草草草我 \(3^{2k}\) 怎么过了???????
加了组 hack。
18 10
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9
9 10
10 11
11 12
12 13
13 14
14 15
15 16
16 17
17 18
18 1
1 10
2 11
3 12
4 13
5 14
6 15
7 16
8 17
9 18
然后我的代码还是常数太小冲过去了???甚至跑得比半半在线卷积还快???
把两部分代码拼在了一起。
【UER #4】被粉碎的数字
题解
一眼数位 dp。
我们考虑在状态中记录,目前从低往高考虑到了第几位;已考虑部分的 \(f(x)-f(kx)\);\(kx\) 进位后还没有计算的值;目前已考虑部分是否合法。
总状态数大约是 \(\log_Bv\times2B\log_Bv\times k\times2\) 的。(\(B=10\),认为 \(k\ll v\))
直接 dp 即可。
转移复杂度还要乘上 \(B\)。
总复杂度 \(O(kB^2\log_B^2v)\)。
【UER #5】万圣节的南瓜灯
题解
合法等价于树。
点减边容斥一下,我们转化为判断剩余的图是否联通。
注意到如果点减边等于 \(1\),那么由于初始点数 \(nm\),边数 \((2n-1)m\),我们得到最后剩下的边数为 \(nm-k-1\),因此用掉了 \((n-1)m+k+1\) 条边,于是 \(4k\ge(n-1)m+k+1\),从而点数是 \(O(k)\) 级别的。
故直接把所有点掏出来连边判断即可。
【UER #5】万圣节的数列
题解
经典题。
考虑把奇偶分开,前一半奇数,后一半偶数,转化成除二的子问题(值域除二)。
显然两者之间不会存在一个 \(\ge3\) 的等差子序列。
当序列中所有值相等时,直接任意排列即可。
总复杂度 \(O(n\log v)\)。
【UER #5】万圣节的糖果
题解
感觉很有趣啊!
以下设有 \(m\) 个数,\(n\) 堆。
考虑从小到大依次加入数。
假设初始时各堆均可以为空。假设前 \(a\) 个堆开头为奇数,后 \(n-a\) 个堆开头为偶数。
考虑加入一对数 \(2k-1,2k\),则开头为奇数的序列数不会发生变化。
但是并不是各堆均可以为空的,因此考虑容斥。
设前 \(a\) 个堆开头为奇数,后 \(b\) 个堆开头为偶数,可以为空的方案数为 \(f_{a,b}\)。
设前 \(a\) 个堆开头为奇数,后 \(b\) 个堆开头为偶数,不可以为空的方案数为 \(g_{a,b}\)。
则
我们要求的答案即为
设 \(F_n=\sum_j\binom njf_{j,n-j}\),\(G_n=\sum_j\binom njg_{j,n-j}\),则我们有
二项式反演一下,得到
只用求出 \(F_0\sim F_n\) 即可。这个是平凡的,因为我们有
总复杂度 \(O(n^2+n\log m)\),使用卷积容易优化到 \(O(n\log m)\)。
【UR #10】汉诺塔
题解
这个,我们考虑解决一根柱子上 \(n\) 个点的排序。
如果 \(n=1\),直接返回即可。
否则,分上一半下一半,把上一半排序后倒置,下一半同理,然后归并到一根柱子上即可。
总操作次数为 \(O(n\log n)\) 的。
【UR #10】世界线
题解
忽视掉询问次数的限制,我们期望得到一个怎样的构造?
\(n=1\) 不用构造。
\(n=2\) 无法构造。
\(2\nmid n\) 可以通过成对匹配来构造。即,第一次连接 \((1,2)(3,4)\dots(n-2,n-1)\),第二次连接 \((2,3)(4,5)\dots(n-1,n)\)。
\(2|n\) 可以忽略第 \(n\) 项,转化成 \(n-1\) 的问题。
这样的询问次数是 \(O(n^2)\) 的。
随机化一下,每轮次数就是大约 \(n^2/8\) 的。
明显过不去。
能不能稍微优化一下?
考虑一个杨表状结构,满足第 \(i\) 行恰有 \(T+1-i\) 个格子,共有 \(\frac{T(T+1)}{2}\) 个格子。
第一轮把每行连起来,第二轮把每列连起来。
这样每轮的联通块个数会是 \(O(T)\) 级别的。
剩下的 \(n-\frac{T(T+1)}{2}\) 个节点个数显然是 \(O(T)\) 的,直接按前面的暴力做法去做即可。注意剩下部分大小不可恰好为 \(2\),且 \(T\) 必须足够大以免寄掉。
查询时,我们每次只用不超过 \(2T\) 次查询,即可知其当前所属联通块。
最后按照两组询问分别对应的联通块大小,容易回推出其原本所属的位置;暴力部分直接跳链即可。
查询次数显然不超过 \(4nT\),其中 \(T=\sqrt{2n}\)。
考虑到如果随机排列原串,则每次查询时所遇到的节点个数不会很多,我们猜测这就能过了。
【UR #11】元旦老人与丛林
题解
我会猜结论!
一张图 \((V,E)\) 合法当且仅当对其任一张非空子图 \((V',E')\) 均有 \(|E'|\le2|V'|-2\)。
后者的必要性是显然的,充分性不会证 OvO。
考虑怎么判断这种东西。
如果规定一张子图 \((E',V')\) 的权值为 \(|E'|+2-2|V'|\),则合法等价于其任一非空子图权值均非正。
考虑构造一个最大权闭合子图模型,如果选了一条边就必须选其对应的点,每条边权值为 \(1\),每个点权值为 \(-2\)。显然可以最小割。
但这样是在一张子图权值是 \(|E'|-2|V'|\) 情况下的解,无法判断存在一张子图满足 \(|E'|=2|V'|-1\) 及 \(|E'|=2|V'|\) 的情况。
因此我们考虑从图中删去某个点,那么合法等价于对任意一种删点方案均使源点满流。
怎么实现?
我们先不删点跑一次流,如果未满流肯定不合法。
否则,我们考虑通过找交错路流回汇点来将其满流。使用匈牙利算法之类的东西来实现这个是容易的,并且单轮复杂度只用 \(O(n)\)。
初始跑流的复杂度容易发现是和二分图最大匹配相同的,于是直接上匈牙利就做完了。
总复杂度 \(O(n^2)\)。常数超级小。
由于这张图看上去比较像正则,不知道可不可以套用那个复杂度分析,实际上随机数据下期望复杂度可能是 \(O(n\log n)\) 的?(忽略掉清空数组的部分)
【UR #11】元旦老人与数列
题解
吉司机线段树板子。
维护区间最小值,次小值,历史最小值,区间加的 tag,区间加的 tag 的历史最小值,最小值在上一次下传标记之后的历史最小值(也就是下传后又要还原了),最小值是否从左 / 右子树转移而来。
下传标记的部分属实比较奇妙,还是自己写一遍清楚。
这个东西只能分析到 \(O(q\log^2n)\) 的复杂度,但是目前还不能卡满。所以直接写就是了。
新年的破栈
题解
考虑贪心。
如果当前还未加入栈的元素中最小元素小于目前栈顶栈底,则保持入栈。
否则弹出栈顶或栈底。
容易发现这样最优。
新年的网警
题解
\(p\) 合法等价于存在另一个节点 \(q\) 使得 \(\exist C,\forall c\neq p\land c\neq q,\operatorname{dist}(c,p)-\operatorname{dist}(c,q)=C\)。
容易证明总不妨令 \(C\) 满足 \(\in\{-1,0,1\}\)。
对于 \(C=1\) 的情况,\(\deg(p)=1\)。
对于 \(C=-1\) 的情况,\(\deg(p\text{ 的一个邻居})=1\)。
对于 \(C=0\) 的情况,忽略掉边 \((p,q)\)(如果存在)后,\(p,q\) 所连的点集完全相同。
我们分 \((p,q)\) 是否存在讨论。
对于 \((p,q)\) 不存在的情况,就是所连点集相同。
否则,就是所连点集与自身构成的点集相同。
直接随机点权进行哈希即可快速判断。
复杂度 \(O(n+m)\)。
新年的繁荣
题解
首先,我们总不妨把权值相同的缩在一起。容易发现不劣。
然后考虑 Boruvka,我们考虑对每个联通块快速找到其对应连接其他联通块的最大边。
考虑构造一个数据结构 \(A\),支持:
- 插入一个数 \(v\)。
- 查询当前数集中和 \(v\) 按位与最大的数。
我们假设其单次操作复杂度为 \(T\),预处理复杂度 \(W\)。
我们将目前各个联通块依次称为 \(S_1,S_2,\dots,S_t\),那么我们找到每个联通块和之前、之后的联通块的最大边。这个可以正反两遍操作 \(A\) 实现。
这样单轮的复杂度即为 \(O(nT+W)\),进行 \(O(\log n)\) 轮的总复杂度即为 \(O((nT+W)\log n)\)
使用 meet in the middle 容易做到 \(T=O(2^{m/2}),W=O(2^m)\)。
这个松一松就能过了。
新年的腮雷
题解
考虑二分答案。
我们从一个上界 \(v\) 开始,那么我们可以由其反推出 \(v-b_1,v-b_2,\dots,v-b_m\) 等上界。(如果当前数是通过拆得到的)
然后我们每次把最大数能拆则拆,不能拆则摆即可。
总复杂度 \(O(n\log n\log(nv))\)。
然后就光荣 WA 48pts 了。
因为你不知道最大数究竟能不能拆。这就比较寄。
。。。
实际上只要从 \(v-\min b+1\sim v\) 之间都合法即可。
暴力实现它当然会 TLE。
注意到我们可以用线段树去维护区间加区间最小值,直接做即可。
【UR #12】实验室外的攻防战
题解
合法等价于此前每个顺序对此后仍为顺序对。
我们考虑设 \(u_{A_p}=v_{B_p}=p\)。
那么合法等价于不存在两个数 \(x<y\),满足 \(u_x<u_y\land v_x>v_y\)。
考虑对每个 \(y\),找到最大的 \(v_x\),使得 \(x<y\land u_x<u_y\)。
显然可以直接对值域扫描线然后 BIT 维护。
总复杂度 \(O(n\log n)\)。
【UR #12】密码锁
题解
结论:竞赛图缩点后形如一条链。
枚举那个强连通分量,期望容易表示成
其中 \(g(A)\) 表示 \(A\) 为强连通分量的概率,而 \(f(A,B)\) 为 \(A\) 到 \(B\) 均为单向边的方案数。
这个方法不够优秀。
其实,我们可以直接写成
理由是直接枚举链上的一个非空前缀。
考虑枚举 \(A\) 与 \(S-A\) 之间的特殊边集,那么我们得到若干条限制:\([i\in A]=[j\in A]\) 或者 \([i\notin A]=[j\notin A]\)。
连完边后,得到若干个联通块。
如果某个联通块不合法,肯定无贡献。
否则,每个联通块内部的 \(\in A\) 情况恰有 \(2\) 种。
我们用一个背包计算出每种 \(|A|\) 方案对应的概率,然后再统计那些非特殊的边所带来的贡献。
这样单轮复杂度即为 \(O(n^2)\)。
总复杂度 \(O(n^22^m)\),松一松就能过了。
如果直接把每个联通块的状态指数级做一遍,最后再背包,复杂度即为 \(O(n2^m+n^2)\)。
【UR #12】a^-1 + b problem
题解
题目可以转化成若干次给定 \((A,B,C,D)\) 询问 \(\sum_j\frac{Aa_j+B}{Ca_j+D}\)。
判掉边界情况,就是给定 \(x\) 询问 \(\sum_j\frac{1}{a_j+x}\)。
这个东西,我们分治 FFT 求出分子分母然后多点求值就好了。
代码的话,狗都不写好吧。
虽然就是拉个板子的难度但是多点求值还是太混乱邪恶了,因此鸽子。
【UR #13】Yist
题解
考虑倒序操作,我们从大到小加入一个元素 \(x\)。
找到往前往后第一个 \(<x\) 的数,查询此段区间内 \(\ge x\) 的数的数目即可。
直接做复杂度是 \(O(nq\log n)\) 的。
使用 BIT + 并查集,卡卡常就可以冲过去了。
【UR #13】Ernd
题解
设 \(f_p\) 表示从 \(p\) 开始接所能拿到的最大答案。
设 \(h(u,v)\) 表示 \(u\) 能否赶上 \(v\),即 \(h(u,v)=[b_v-b_u\ge|a_u-a_v|]=[a_v-b_v\le a_u-b_u\land a_u+b_u\le a_v+b_v]\)。
设 \(r_u\) 表示从 \(u\) 开始最多全连到谁,即 \(r_u=\max\{p|u\le p\le n,\forall_{u\le j<p}h(j,j+1)=1\}\)。
那么我们有转移
设 \(g_p=\max_{p<t\land h(p,t)=1}f_t\),且不存在时为 \(0\)。
那么就是
由于 \(y=x^2\) 是凸的,所以在 \(g_p\) 的定义处,我们可以改定义成
容易验证最终答案不会改变。
那么,我们可以考虑每次把一段 \(r_p\) 相同的区间的 \(g\) 一起计算出来,然后斜率优化算出区间的 \(f\),继续更新前面的答案。
那么问题在于如何计算 \(g\)。
由于限制是三维的,我们可以对下标维进行 cdq 分治,做到 \(O(n\log^2n)\) 的总复杂度。极限卡常或许能过,不过意义不大。
但是真的必须如此吗?
注意到 \(h(u,v)=[[a_u-b_u,a_u+b_u]\subseteq[a_v-b_v,a_v+b_v]]\),因此同一个连续段对应的区间是一种包含的关系,\(f\) 也是单调的,\(g\) 也是单调的。
然后就不会了。开摆,贺题解。
草怎么直接用单个 BIT 维护是对的啊。这题解写的个什么东西。
哦,就,如果 \([a_u-b_u,a_u+b_u]\subseteq[a_v-b_v,a_v+b_v]\),那么必然有 \(b_u<b_v\),从而 \(u<v\)?
大意失荆州,直接按 \(a-b\) 从小到大排序然后直接转移就好了,甚至 \(g\) 的定义都不必改,对每个连续段的凸壳可以同时维护。
总复杂度 \(O(n\log n)\)。
【UR #13】Sanrd
题解
假设当前数是 \(n\),所得的数是 \(p\)。
那么,\(p\) 显然就是 \(n\) 的非严格次大质因子,当不存在时即为 \(0\)。
考虑由于是求前缀和,不妨枚举答案,然后统计方案数,我们有
其中 \(S(x,p)\) 表示 \(1\sim x\) 中有多少数满足所有质因子均不大于 \(p\)。也即所谓「质数前缀统计」。
所有在考虑范围内的 \(S(x,p)\) 数目大致是
的。甚至可以分析一个更紧的界,
不过这没啥用,因为后面还是得用到 \(O(n^{3/4}/\log n)\) 级别的 \(S\)。
而对于 \(S(x,p)\) 的计算,假设我们把 \(1\sim\sqrt n\) 内的质数依次称为 \(p_1,p_2,\dots,p_m\),那么我们就有
于是直接 dp 即可。只用记录 \(p_k^2<x\) 的状态,因为否则 \(p_k^2\ge x\) 总有
一直递归到某个 \(p_j^2<x\) 为止。这个可以直接对每个 \(x\) 数论分块来实现。
对于 \(p_k^2<x\) 的状态,一共只有 \(O(n^{3/4}/\log n)\) 种。
我们接下来只用考虑每种 \(S(x,p)\) 可能出现几次。
显然即为
所以我们还要快速统计出形如
的信息,其中 \(n\) 取遍块处点值。
这个东西,我们考虑到所有 \(n\) 以内的合数均有一个 \(\le p_m\) 的质因子,所以我们做一个容斥,转化为
其中 \(Q(n,p_k)\) 表示 \(1\sim n\) 中和 \(p_k\sim p_m\) 均互质的数的个数。
然后同样递推就好了。
同样的,当 \(x\le p_k^2\) 时,有
于是类似实现即可。
总复杂度 \(O(n^{3/4}/\log n)\)。
然后就 TLE 了。
这种递推过程中由于出现了 \(\lfloor x/p_k\rfloor\),不能方便地通过求前缀和优化,这部分复杂度达到了 \(O(n^{3/4})\),而数论分块的常数又很大,于是就 T 了。
不过这种形式本来就不好做,使用 BIT 维护的常数也很大。
摆了。
【UR #14】最强跳蚤
题解
完全平方数的限制一般可以通过划分等价类解决。
规定两个正整数 \(a,b\) 同属一个等价类,当且仅当存在正整数 \(c,p,q\) 满足 \(a=cp^2\land b=cq^2\)。每个等价类内最小的元素称为代表元,其同时也是一个通用的 \(c\)。
对这道题目,我们设一个点的权值为其到根的连接的边权乘积,那么两个点之间路径合法等价于其同属一个等价类。
不过这并没有什么卵用,因为哪怕是等价类的代表元其值域仍旧很大。。。
注意到这个和异或很像,我们质因数分解,然后给每个质数一个随机权值,改成异或即可。
唯一的问题在于质因数分解,这个可以先筛出 \(\sqrt n\) 以内的质数然后再做。哈希时直接 mt19937_64
即可。
【UR #14】人类补完计划
题解
显然合法的图形如一颗基环树。
然后权值就是 \(2^{|V|-\text{叶子节点个数}}\)。
我们发现这个权值很有特点,不妨枚举点集 \(A\),求出有多少点集 \(V\) 边集 \(E\) 满足合法且 \(A\) 均不是 \(V\) 的叶子。
这个不是很行,没法直接算。考虑一些小技巧。
考虑设 \(f(V,A)\) 为 \(V\) 合法且 \(A\) 中均是叶子的方案数。
设 \(g(V,A)\) 为 \(V\) 合法且 \(A\) 中恰是叶子的方案数。
那么答案即
而我们有
于是作子集反演,我们得到
关键在于 \(f(V,A)\) 怎么求。
考虑到就是 \(A\) 中节点随便往 \(V-A\) 中连一条边,我们只用求出 \(V-A\) 集合的基环树数目即可。
总而言之,问题被转化为了对每个 \(V\) 求其对应基环树数目 \(h(V)=f(V,\varnothing)\)。
设 \(T(A)\) 为 \(A\) 集合生成树的数目,\(C(A)\) 为 \(A\) 集合形成的环数。前者可以矩阵树定理计算,后者可以暴力 dp 直接得到,复杂度且按下不表。
考虑枚举环 \(A\) 的形态,对每个环上的点和环外部分建立集合幂级数,那么就是对 \(|A|\) 个集合幂级数求子集卷积,暴力实现的复杂度为 \(O(|A|(n-|A|)^22^{n-|A|})\) 的。
总复杂度即为
不像是能过的样子。
仔细想想,我们真的要枚举 \(A\) 集合中每个点对应的树集合的集合幂级数吗?
我们可以直接对 \(A\) 集合外的每棵树枚举其所连的父亲,也即环上某个节点,合并时即为将 \(2^{n-|A|}\) 个集合做子集卷积。
这个可以用半半在线卷积直接做到 \(O((n-|A|)^22^{n-|A|})\)。
总复杂度于是即为 \(O(n^23^n)\)。当然还是过不去。
考虑怎么继续优化。
考虑直接不单独枚举环的形态,而是直接对基环树按环的顺序 dp,每次加入一颗子树,而开始时子树的根应当为环上最小点。
那么 dp 状态中可以记录环上开头、末尾元素以及当前点集,从而形如
除以二是因为一个环可能被正反算两遍。然后计算答案时可能出现一条边被视作环的情况,这应当被排除,故作容斥。
暴力转移的复杂度是 \(O(n^33^n)\) 的。
但由于子集卷积可以优化,每次把暴力卷积换成子集卷积,复杂度即可做到 \(O(n^52^n)\)。
\(n^5\) 比 \(2^n\) 还大,怎么会是呢。
注意到对于每个点 \(p\),其对应的集合幂级数可以预处理,而每个 \(t(p,q,A)\) 可以同时按 \(|A|\) 占位元顺序使用半半在线卷积转移。
这样转移的复杂度就在于枚举 \(q,o,p\) 然后枚举占位元进行对应位置卷积,复杂度才为 \(O(n^52^n)\)。
仔细观察,容易发现我们的 \(q\) 可以在最外层进行枚举,内部转移时可以将关于一个 \(p\) 可以合并的状态 \(o\) 都压在一起,这样每次转移时就不用枚举 \(o\) 了。
这样的时间复杂度即为 \(O(n^42^n)\),空间复杂度即为 \(O(n^22^n)\)。
一种有效的卡常方法是减少 FMT 次数,直接对集合幂级数操作,最后再 FMT 回来。
最后我们再看最终答案的计算。
答案为
于是该部分暴力即可做到 \(O(n^22^n)\)。
咋还卡 long long
空间的。/fn
然后就 \(\rm70pts\) 了。
考虑怎么继续优化复杂度。
核心仍在于 \(h\) 的计算。
考虑先统计基环内向树森林数目,然后通过集合 \(\ln\) 求出基环内向树数目,进而推出基环树数目。
考虑构造双射:对集合内每个点往其余点随意连一条边,容易发现每种连边方案对应了一颗基环内向树。
对取 \(\ln\) 后的每个联通块,考虑其和基环树数目,如果环是一个重边则会被统计恰好 \(1\) 次,否则会被统计 \(2\) 次。
因此同样去掉树的情况再除二即可。
时间复杂度 \(O(n^32^n)\),空间复杂度 \(O(n2^n)\)。
瓶颈在矩阵树定理上,使用逐点牛顿迭代法计算生成树个数即可优化到 \(O(n^22^n)\)。
【UR #14】思考熊
题解
二进制分组板子。Unknown v2。
考虑线段树上二进制分组,对一个节点其为合并好的当且仅当下一个达到其长度的区间已经存在,复杂度可以均摊。
然后对每个节点考虑如何支持 \(O(n^{1+\varepsilon})\) 预处理 \(O(n^{\varepsilon})\) 查询。
我们可以建出虚树,对虚树上每个节点进行换根 dp,然后尝试在查询时快速找到该节点信息最小在哪个子树中、最大在哪个子树外。
这个可以用 dfn 序 + ODT 直接维护。
然后要求快速查询点对间距离,这个可以树剖维护。
总复杂度 \(O(n+q\log^2n)\)。
被卡常了,\(\rm 97pts\),开摆。
共价大爷游长沙
题解
考虑给每条路径一个 \(0\sim2^{64}-1\) 内的随机权值,而一条边的权值为经过其的路径的权值异或。
我们判定一条边合法,当且仅当其与目前所有路径权值的异或相等。正确率容易分析。
LCT 维护一下即可。
复杂度 \(O(n+q\log n)\)。
【UER #6】票数统计
题解
如果 \(x\neq y\),那么显然其中哪条成立易知。
而对于 \(x=y\) 的情况,其表示前 \(x\) 个或后 \(x\) 个均通过,因此该种限制只用保留最大一项。
暴力枚举一下是前 \(x\) 个均通过,还是后 \(x\) 个均通过,还是均满足,暴力容斥一下求出答案。不存在 \(x=y\) 的情况时不妨直接记为 \(x=0\)。当 \(2x\ge n\) 时要特殊处理。
接下来只用考虑每种已经唯一确定的限制均合法的情况。
每种限制表示前 / 后 \(a\) 个人中恰有 \(b\) 个支持。
考虑枚举一下总支持人数,那么每条信息相当于是每个前缀中恰有若干个支持,也就是每个区间中恰有若干个支持,直接一个组合数即可算出方案数。
总复杂度 \(O(nm)\)。
【UER #6】寻找罪犯
题解
草这个原来真可以 2-SAT,我还以为不行。。。
暴力建图点数目是 \(O(n)\) 的,边数目是 \(O(n^2)\) 的。
使用前缀优化建图即可优化到 \(O(n)\) 的点数和边数,总复杂度 \(O(n)\)。
【UER #6】逃跑
题解
方差是什么?
于是只用求出 \(\operatorname E\!X\) 和 \(\operatorname E\!X^2\) 即可。
怎么求呢?
先考虑求 \(\operatorname E\!X\) 的部分。
考虑反向统计贡献,我们统计每个位置有多少种方案被走上至少一次。直接 dp 记录每个时刻当前位置,每个 dp 复杂度 \(O(n^3)\)。由于要枚举做出贡献的点,总复杂度 \(O(n^5)\)。\(\operatorname E\!X^2\) 也可以类似地做到 \(O(n^7)\)。
这样还不够。考虑怎么继续优化。
考虑容斥,容易得到在 \(n\) 时刻恰好第一次走到 \((x,y)\) 的方案数满足
其中 \(A_{x,y,t}\) 为花 \(t\) 步从 \((0,0)\) 走到 \((x,y)\) 的方案数。
在前 \(n\) 个时刻中 \((x,y)\) 被走到至少一次的方案数为
故可在 \(O(n^4)\) 内算出所有 \(F_{x,y,n}\),也就算出了 \(\operatorname E\!X\)。
对于求 \(\operatorname E\!X^2\) 的过程,我们枚举点对 \((x_1,y_1)(x_2,y_2)\)。\((x_1,y_1)=(x_2,y_2)\) 的情况是平凡的,我们接下来考虑 \((x_1,y_1)\neq(x_2,y_2)\) 的情况。
枚举第一个到达的是哪个点,譬如 \((x_1,y_1)\),然后容易考虑其下一步往 \((x_2,y_2)\) 走的情况。但由于实际上可能会出现先到达 \((x_2,y_2)\) 的情况,故应当对此做容斥。由于子问题还会这么干,容易做出一个链状的「交替容斥」。也即
这个形式太丑了。
我们设生成函数
稍微化一下,转成
再设
则即
由于
于是我们其实可以直接把每个 \(D_{x_1,x_2}\) 叠在一起,每个 \(U_{x_2-x_1,y_2-y_1}\) 叠在一起,最后再计算贡献。
于是计算 \(\operatorname{E}\!X^2\) 部分答案的复杂度即可做到 \(O(n^3)\)。
总复杂度 \(O(n^4)\),瓶颈在计算 \(A,D,U\) 上。如果允许 FFT 则为 \(O(n^3\log n)\)。
【UNR #1】争夺圣杯
题解
考虑建出笛卡尔树,每次统计子树中经过根节点的区间的贡献。
容易发现每个贡献均形如区间加等差数列。
拿两个差分数组分别维护一下斜率和截距即可,最后做一次前缀和得到结果。
总复杂度 \(O(n)\)。
【UNR #1】合唱队形
题解
推完后才发现自己读错题了。
原来询问的小写字母串中会有重复字符吗。大受震撼。
同样删除无效限制,那么不会多于 \(n-m+1\) 个限制。
min-max 反演一下,期望最小步数转化为每个子集完全覆盖的期望步数,暴力枚举子集,复杂度 \(O^*(2^{n-m})\)。当 \(m\ge n/2\) 时可以这么干。
考虑 \(m\) 比较小的情况。
同样 min-max 反演,把柿子列出来,为
其中 \(a_n=AH_n\),\(A\) 为总课程数,\(H_n\) 为调和数。
注意到每个 \(S_j\) 对应的课程都是一段长度为 \(m\) 的区间,因此决定了新课程增加量的只有前 \(m\) 个区间,直接状压即可,复杂度 \(O^*(2^m)\)。
具体地,我们在状态中记录下 \(A\) 的大小和前 \(m\) 个集合是否选择即可。
总复杂度 \(O^*(1.41^n)\)。
【UNR #1】Jakarta Skyscrapers
题解
不妨 \(a\le b\)。
首先,如果 \(\gcd\{a,b\}\nmid c\lor b<c\),那么无解。
否则,我们不妨先令
则应有 \(a\perp b\),\(a,c\le b\)。
考虑尝试构造出 \(1\)。
考虑欧几里得算法,已知 \(a,b\),怎么在 \(O(\log(b/a))\) 步内构造出 \(b\bmod a\)。
我们考虑依次构造 \(b-a,b-2a,2a,b-4a,4a,\dots,b-2^ka\),且 \(2^{k+1}a>b\)。
然后我们再对 \(b-2^ka\) 依次尝试减去 \(2^{k-1}a,2^{k-2}a,\dots,2a,a\),如果可减就减。最后所得即为 \(b\bmod a\)。
这样每步复杂度 \(O(\log(b/a))\),迭代共 \(O(\log n)\) 轮,总复杂度即为 \(O(\log n)\)。
当某时刻 \(a=1\),直接结束当前过程。
然后我们就在 \(O(\log n)\) 步内构造出了 \(1\)。
然后我们取出最开始的 \(b\),类似地依次构造 \(b-1,b-2,2,b-4,4,\dots,b-2^k\),直至 \(b-2^{k+1}<c\)。
接下来再每步尝试减去 \(2^{k-1},2^{k-2},\dots,1\),这样又只花了 \(O(\log n)\) 步。
总步数级别 \(O(\log n)\),可以通过。
【UR #15】奥林匹克五子棋
题解
如果 \(k=1\),显然无解。
如果 \(k=2\),有解当且仅当 \(n=1\lor m=1\),可以直接错位构造。
如果 \(k\ge3\),我们这么构造:
0101010101...
0101010101...
1010101010...
1010101010...
0101010101...
0101010101...
.............
取一个 \(n\times m\) 的左上角子矩形,其中 \(2|m\) 或 \(2\nmid n\),总有 \(0,1\) 数目相等或 \(0\) 比 \(1\) 多 \(1\) 个,且显然不存在三子连珠。
然后就做完了。
【UR #15】奥林匹克环城马拉松
题解
先考虑树的情况。
每条边被正反走过一次,我们不妨定一个根来做。
首先边权都得是偶数,我们不妨除二。
我们假设「更换起始边后两序列相同」得到的是不同的序列。
假设 \(\deg(p)=\sum_sw(p,s)\)
假设 \(f_p\) 为 \(p\) 子树内从 \(p\) 开始走的选法总数目。
则
最后由于是圆排列,答案即为 \(f_{\mathrm{root}}/\deg(\mathrm{root})\)。
稍微移一下系数就可以发现,设 \(d_p=\sum_qw(p,q)\),则答案即为
然后我们发现我们是憨憨:直接用 BEST 定理就可以得到相同的结论;因为每条树边可以拆成一对有向边,枚举一下把哪些边拆成其中一个方向,就可以用 BEST 定理得到同样的结论了。
接下来考虑基环树的情况。
显然环边奇偶性相同,树边均偶数。
假设一个环上的点两侧的边数分别为 \(t_1,t_2\),那么该点一定恰好被从环上进入 \(\frac{t_1+t_2}{2}\) 次。设为 \(r_p\)。
由于是环排列,我们总不妨令第一步不走入子树。故对于这个点的子树,我们可以类似于之前的方法计算出贡献 \(f_p\binom{r_p+\deg(p)-1}{\deg(p)}\)。
然后就是环上有多少种环排列的走法的问题了。
我们假设环上各边数目依次为 \(t_1,t_2,\dots,t_m\)。
注意到值域很小,考虑暴力枚举有某条边有多少正着走的方案,从而得到每条边有多少个正 / 反走的方案。
假设有 \(x_1,x_2,\dots,x_m\) 个正走的,\(y_1,y_2,\dots,y_m\) 个倒走的,其中 \(x_j+y_j=t_j,x_j+y_{j+1}=r_j\),由 BEST 定理,方案数即
注意到
从而可以 \(O(n)\) 递推。
总复杂度 \(O(nt)\),可以通过。
基础数据结构练习题
题解
考虑线段树维护,每个节点维护区间最大最小值和区间和。
如果区间全部相同,可以转化为区间加的 tag。
如果区间最值相差 \(1\) 且开根后不同,则也打区间加的 tag。
否则暴力下传。
我们猜测这么做复杂度是对的。(看着就很对的样子!)
简单证明一下,拿 \(\sum\log\log\text{区间极差}\) 做势能,每次区间加带来的抬升量是 \(O(\log n\log\log v)\) 的,初值是 \(O(n\log\log v)\) 的,每次暴力下传降低量是 \(\Omega(1)\) 的,感觉复杂度毛估估就很对!
这样总复杂度即为 \(O((n+q\log n)\log\log v)\)。
【UR #16】破坏发射台
题解链接。
【UR #16】破坏蛋糕
题解
我们不妨先暴力求出所有交点,然后对直线进行排序。
首尾块显然不封闭,我们考虑相邻两条直线之间怎样是封闭的。
考虑维护出每条直线相对于给定直线的极角,显然其在 \((0,\pi)\) 间。不妨假设依次为 \(\alpha_1,\alpha_2,\dots,\alpha_n\)。
考虑 \(p\) 与 \(p+1\) 之间怎样是合法的。
显然封闭相当于补全上、下两个缺口。容易发现这等价于 \(\exists\,i\le p,j>p,\,\alpha_i>\alpha_j\) 且 \(\exists\,i\le p,j>p,\,\alpha_i<\alpha_j\)。
证明?我不会我不会。其实是好证的。
计算一下前后缀最值即做完。
为了防止掉精,我直接使用了极角余弦值的分数形式进行比较。
【UER #7】短路
题解
贪心题!
注意到我们总不妨只往右、下走。
考察第 \(n+1\) 个格子,我们总不妨令前后选法对称。
容易证明,对于第 \(n+1\) 个格子对应的类型,我们总不妨取完。
问题变成从起点走到对角线的最小代价。
考虑推进一个位置时,我们除了加上该部分代价,再加上前缀最小值的贡献。
容易证明这么贪是对的。
总复杂度 \(O(n)\)。
【UER #7】天路
题解
很牛的一道题!
注意到我们可以每隔 \(1.05\) 倍长度做一次,这样我们只用处理 \(\log_{1.05}v\) 种长度对应的答案。
对每种长度,我们考虑双指针。由于有效的指针只有 \(O(n)\) 对所以只用做 \(O(n)\) 次。
现在要快速支持插入或删除一个元素,然后查询最长被覆盖的连续段长度。怎么做?
直接拿一个线段树或 set
维护,单次复杂度 \(O(\log n)\),总复杂度 \(O(n\log n\log_\alpha v)\),其中 \(\alpha=1.05\)。
\(\log_\alpha v\) 大约是 \(300\) 的样子,看上去不是很能过?
查询时由于只用得到最长值,我们可以每次仅仅查看一个值如果作为当前连续段的最大数,其向前后分别能扩展多少。
我们可以预先建出笛卡尔树,得到每个点的基于上界的边界,然后考虑快速找到基于下界的边界。
我们再建出一个小根的笛卡尔树,然后就是快速查询距离不大于某个值的最远祖先,二分单调栈即可。加上决策单调性的剪枝后常数很小。
复杂度仍为 \(O(n\log n\log_\alpha v)\),由于常数很小,容易通过。
然后发现大意了,直接按两个端点搞双指针就好了。。。复杂度 \(O(n\log_\alpha v)\)。
直径拆除鸡
题解
我们这么构造:
注意到有多条直径时具体取哪条是可以任意指定的,直径上一个节点往直径外的节点连边长度不能超过当前点离直径端点的距离。
因此我们总不妨往最靠中间的节点塞一个子结构,满足直径不大于当前直径 \(-2\)。
最后多余的部分可以往最后一层直径等于 \(3\) 的中点嗯塞。
毛估估感觉这样是最多的,大概是 \(O(n\sqrt n)\) 级别的。
然后实际上可能有的时候去掉最外面几层答案会更大,可以枚举一下去掉多少层;反正不会超过 \(\sqrt n\) 层。
总复杂度 \(O(n)\)。
快乐游戏鸡
题解
我们算出路径上的最大 \(w\),来确定至少要把 \(w\) 刷到多少才能走。
然后考虑从 \(s\) 开始刷 \(w\)。
我们知道刷 \(w\) 的过程是个凸函数,考虑计算出每个子树的这个凸壳。
不妨离线下来,长链剖分维护出单调栈,进行启发式合并,然后直接嗯做就好了。
计算树上路径最值的部分偷了个懒,写了树上倍增,总复杂度 \(O((n+q)\log n)\)。
【UNR #2】UOJ拯救计划
题解
观察一下,假设实际用到了 \(t\) 种颜色,只有 \(t\le2\) 有意义:如果 \(t\ge3\),同构的方案数共有 \(k^{\underline t}\) 种(相当于做了个映射),必然为 \(6\) 的倍数,于是无需统计。
因此我们分类讨论:
- 如果 \(m=0\),总方案数显然是 \(k^n\)。
- 如果 \(m>0\) 且是二分图,先 \(\binom k2\) 枚举选择哪两种颜色,然后二分图每个联通块有 \(2\) 种选法,直接计算即可。
- 否则,答案模 \(6\) 为 \(0\)。
总复杂度 \(O(n+m)\)。
【UNR #2】黎明前的巧克力
题解
即选出两个不交集合,使得其异或和相等。最后减去均不选的情况即可。
我们考察不被选择的元素状态;显然其异或应当等于所有元素的总异或值;而被选择的那些元素任意的集合分割方案均是合法的。
因此,我们设
并记 \(U=\{1,2,3,\dots,n\}\),则答案即为
其中幂级数乘法被定义为异或卷积。
注意到值域只有 \(10^6\),考虑 FWT。
考虑 FWT 的过程,我们 FWT 时 \(x\rightarrow y\) 的贡献系数为 \((-1)^{\operatorname{popcount}(x\operatorname{bitand} y)}\),因此 \(2+z^a\) 对 \(b\) 位置的贡献系数为 \(2+(-1)^{\operatorname{popcount}(a\operatorname{bitand} b)}\)。
于是我们统计出每个 \(b\) 会被多少个 \(a\) 做出 \(3\) 的贡献,这个是可以一遍 FWT 计算得到的,复杂度 \(O(v\log v)\)。
然后取 \(3\) 的该次幂,求出 IFWT 后的 \(\mathop\oplus_{1\le i\le n}a_i\) 项结果,可以直接 \(O(v)\) 解决。
总复杂度 \(O(n+v\log v)\),可以轻松通过。
【UNR #2】积劳成疾
题解
即求
看上去不好做。
考虑按笛卡尔树的方法来 dp。
假设
那么,我们枚举 \(a\) 中最左最大值,及其所在位置,则有
预处理一下转移系数,复杂度 \(O(n^3)\)。
新年的XOR
题解
首先,\((2k)\oplus(2k+1)=1\)。
因此 \((2k)\oplus(2k+1)\oplus(2k+2)\oplus(2k+3)=0\)。
当 \(n\equiv0\pmod4\) 时,\(1\oplus2\oplus3\oplus\dots\oplus n=n\);特判 \(n=0\),取 \(0=1\oplus2\oplus3\) 即可。
当 \(n\equiv1\pmod4\) 时,\(2\oplus3\oplus\dots\oplus(n-1)=n\);特判 \(n=1\),取 \(1=2\oplus3\) 即可。
当 \(n\equiv2\pmod4\) 时,\(2\oplus3\oplus\dots\oplus n=n\);特判 \(n=2\),取 \(2=3\oplus4\oplus5\) 即可。
当 \(n\equiv3\pmod4\) 时,\(1\oplus2\oplus3\oplus\dots\oplus (n-1)=n\)。
这样就做完了。
新年的叶子
题解
首先提取出一条直径,然后把所有在任一条直径上的叶子取出。
我们找出直径中点,从其把整颗树分成 \(\ge2\) 个部分。
合法等价于只有一个部分没有被完全摧毁。
我们假设各部分分别有 \(a_1,a_2,\dots,a_m\) 个有效的叶子,共有 \(A=\sum a\) 个叶子。
考虑使用 GF 来描述答案。
枚举最后剩下的部分以及最后一步选法,答案即为
设 \(u=e^{z/A}\),我们只用得到
关于 \(u\) 的结果即可。
仔细观察这个形式会发现该形式是可优化的;简单来说,我们考虑这么做:
考虑解决
容易发现就是一个一次函数复合的形式,直接一次卷积即可搞定。
最后计算完答案后,因为可能枚举到无用叶子,还需乘上对应系数。
【UR #17】滑稽树上滑稽果
题解
结论:最优解肯定不妨是链。
证明可以考虑如果最优解出现一对兄弟 \(u,v\),那么把 \(u\) 子树接到 \(v\) 下面更不劣。
然后去掉所有数的与的贡献后,我们只用最小化顶部的贡献,也就是变成 \(0\) 的代价。
考虑 dp,枚举每个数能通过按位与上一个 \(a\) 转移到谁,最小化转移代价。
预处理一下信息即可做完。
【UNR #3】鸽子固定器
题解
首先按 \(s\) 排序。
如果选择的个数 \(<m\) 个,那总不妨是一段连续的区间,否则不如继续在内部选。
接下来考虑 \(=m\) 的情况,那么一定是选择区间中 \(v\) 最大的 \(m\) 个来计算贡献。
考虑从大到小枚举这最大的 \(m\) 个中的最小元素,依次插入,然后枚举区间来查询即可。
粗暴实现,总复杂度 \(O(nm\log n)\)。
反过来枚举,逐个删除元素,使用双向链表可以优化复杂度到 \(O(nm+n\log n)\)。
新年的拯救计划
题解
显然答案不超过 \(\lfloor n/2\rfloor\),接下来我们来看构造方案。
不妨点标号从 \(0\) 到 \(n-1\),\(n\sim 2n-1\) 是其别称。
设 \(d=\lfloor n/2\rfloor\),则对 \(p=0,1,2,\dots,d-1\),我们依次如下连边:\((p,p+1)(p,p+2)\dots(p,p+d)(p+d,p+d+1)(p+d,p+d+2)\dots(p+d,p+n-1)\)。
容易验证构成树且边不重。
新年的小黄鸭
题解
很厉害的一道题。
假设一个子树 \(p\) 的答案是 \(g_p\),那么考虑枚举重链底部的叶子 \(t\),则有
后半部分贡献容易维护,考虑前半部分,我们可以直接暴力枚举合法的 \(a\),容易发现总数是 \(O(n\log n)\) 的。
最后线段树上 \(O(n\log n)\) 次区间加,\(O(n)\) 次区间查询最小值。
直接做就是 \(O(n\log^2n)\) 的。
新年的促销
题解
首先送的总不妨是买的这些中费用最大的若干。
我们按费用 \(p\) 排序,对每个前缀计算出在该前缀中 \(t\) 元买 \(k\) 袋的最小代价,往后选 \(w\) 最大的若干作为送的部分即可。
总复杂度 \(O(n^2m)\)。
新年的追逐战
题解
做构造题做破防了,于是来看这题。
两个点连边当且仅当对应各维在各图上连边。
考虑各图的某个联通块 \(A_1,A_2,\dots,A_m\) 所构成的子问题。
假设其中有单点,那么带来 \(\prod_{k=1}^m|A_k|\) 的贡献。
否则如果 \(A_1\sim A_m\) 中有 \(t\) 个二分图,那么其带来 \(2^{\max\{0,t-1\}}\) 个联通块的贡献。
假设 \(n\) 个点的非单点简单联通图有 \(f_n\) 的方案生成,非单点简单联通二分图有 \(g_n\) 的方案生成。
那么不考虑单点时答案即为
而单点的贡献为
这些贡献都是容易用卷积计算的,接下来即为考虑如何计算 \(f\) 和 \(g\)。
对于 \(f\),我们先算上单点的部分,然后 EGF 取 \(\exp\) 转化为不要求联通的情况。简单图的数目是 \(2^{\binom n2}\),于是 \(f\) 容易求出。
问题来到二分图这边。考虑设染色二分图有 \(h_n\) 个,显然
注意到一个二分图的染色方案数是 \(2^{\text{联通块数}}\) 的,于是
从而
最后问题转化为计算 \(h\),这个考虑使用 Chirp-Z Transform,或者说也就是组合生成函数。
然后嗯做就好了。
【UR #19】清扫银河
题解
首先容易发现多个第二类操作可以直接叠加,所以第二类操作只会进行不超过 \(1\) 次。
而对于多个第一类操作,我们也容易将其合并成 \(\le m\) 次操作。
从而操作次数一定够用,我们只用考虑判断可行性。
考虑到第二种操作其实就是改变每个点的度数奇偶性,而我们可以用若干个对单个元素的操作来代表所有操作。
因此我们建出线性基,判断初始向量是否在线性基中即可。
使用 bitset
容易优化到 \(O(n^3/w)\)。
【UR #19】通用测评号
题解链接。
【UR #19】前进四
题解
容易想到小粉兔线段树,然而其是 \(O(n+q\log^2n)\) 的。
考虑有没有什么别的做法。
考虑离线下来下标扫描线,那么就是区间取 \(\min\),单点求被取 \(\min\) 了几次。
使用吉司机线段树,复杂度 \(O((n+q)\log n)\)。
【美团杯2020测试赛】子序列
题解
先考虑,如果最终字符串很短,那怎么做。
设 \(f_p\) 表示以 \(p\) 号位置为结尾的此前均未出现过的子序列有几个。
设 \(q_p\) 为上一次 \(p\) 对应字符出现位置,那么
设
则
设 \(h_{p,c}\) 表示 \(p\) 之前的 \(c\) 字符上次出现位置的 \(g\) 值,不存在设为 \(0\)。
则即
不妨考虑在状态里记录下
那么每在末尾加一个字符相当于左乘上一个矩阵。
注意到矩阵乘法有结合律,我们不妨考虑设字符 \(c\) 对应矩阵为 \(\textrm M_c\),则我们每次考虑字符 \(s_n\),先左乘一次 \(\textrm M_{s_n}\),再把所有字符对应的矩阵均左乘 \(\textrm M_{s_n}\)。
最后去掉空串的贡献即为答案。
这样单轮需要 \(O(|\Sigma|^4)\) 的复杂度,进行 \(O(n)\) 轮即为 \(O(n|\Sigma|^4)\) 的。
由于占据空间很小,可以卡进缓存,访问又很连续,取模次数也可以优化,所以实际上很快。
【美团杯2020】查查查乐乐
题解
设 \(f_{n,k}\) 表示考虑了前 \(n\) 个字符,而匹配了 \(k\) 个查查查乐乐的最小代价。
每次在末尾加一个字符,尝试匹配一下即可。
【美团杯2020】平行四边形
题解
考虑找出 \(n+1\) 的一个原根 \(g\),则答案可以构造为 \((x,g^x\bmod(n+1))\)。
合法性证明是容易的。
【美团杯2020】114514
题解
先倒着把每个 4
和上一个未被用的 1
连在一起。
然后依次考虑每个 14
,能和剩下的 1
配就配,否则和 5
配。
然后把 114
和 514
顺次连接即可。
易证这个贪心是正确的。
【UNR #4】序列妙妙值
题解
考虑到,我们可以设 \(f_{k,n}\) 表示把前 \(n\) 个序列分成 \(k\) 部分的最小代价。
则
其中 \(\oplus\) 表示按位异或。
我们作前缀异或,设
则
不妨考虑假设已知 \(f_{k-1,k-1\sim n}\),现在要求 \(f_{k,k\sim n}\)。
则我们每次相当于动态往一个数据结构中插入一个键值对 \((a,b)\),然后给定 \(v\) 查询数据结构中最小的 \(a+(v\oplus b)\)。
注意到值域很小(\(<2^{16}\)),我们把值域二进制分成高八位和低八位。
设 \(h_{A,B}\) 表示当前数据结构中 \((a,b)\) 满足 \(b\) 的高八位为 \(A\) 的最小的 \(a+(B\oplus(b\bmod 256))\)。
那么我们每次插入键值对时只用枚举 \(B\) 的情况,而每次查询时只用枚举 \(A\) 的情况,因此单次插入 / 查询是 \(O(\sqrt v)\) 的。
由于要做 \(k\) 轮,每轮 \(O(n)\) 次操作,总复杂度即为 \(O(nk\sqrt v)\),常数很小,容易通过。
【UNR #4】校园闲逛
题解
设 \(f_{i,j,v}\) 表示 \(i\rightarrow j\) 花费 \(v\) 的方案数。
一种直接的想法是枚举最后一步走的边,按 \(v\) 递增序更新。
这样的复杂度是 \(O(nmv)\) 的。
这个看上去很扯淡,而且常数也不小。
不妨设 \(g_{k,i,j,v}\) 表示从 \(i\) 走到 \(j\),走恰 \(k\) 条边,花费为 \(v\) 的方案数。
这样假设我们要求单个 \(k\) 对应的所有 \(g\),我们可以倍增 \(\log k\) 轮,每轮进行 \(O(n^2)\) 次长为 \(O(v)\) 的 FFT,做到 \(O((n^2v\log v+n^3v)\log k)\)。
我们显然有
我们不妨考虑在对 \(g\) 倍增的同时,对 \(g\) 关于 \(k\) 的前缀和也倍增地计算贡献,从而可以统计 \(f\) 的答案。
而我们知道,当 \(k>v\) 时答案 \(g\) 总为 \(0\),因此我们只用统计 \(0\le k\le v\) 的贡献即可。
这样我们就做到了 \(O((n^2v\log v+n^3v)\log v)\) 的总复杂度。
能不能再给力点啊?
考虑不从倍增入手,直接设
则
也即枚举最后一步选边。
改写成矩阵形式,
或者说
改写一下
即为矩阵求逆。
使用较好的实现即可做到 \(O(n^2v\log v+n^3v)\)。
【ULR #1】多线程计算
题解
考虑当达到 \(k\) 时有多少方案出现 \((x,y)\) 的状态;假设为 \(f_{x,y,k}\),那么对答案的贡献即为 \([(x,y)\text{ is ok}]f_{x,y,k}F_k/(nm+1)\binom{nm}{k}\)。
设在 \(n\times m\) 的网格中填 \(k\) 个位置使得各行各列均有元素的方案数为 \(g_{n,m,k}\),那么我们有
理由是考虑翻转每个位置的状态。
而我们有
从而
于是答案即为
设
则答案即为
设
显然可以通过对 \(2\) 维分别做一次卷积实现。
总复杂度 \(O(nm\log(nm))\)。
【ULR #1】服务器调度
题解
首先毫无疑问,我们对每种颜色维护其虚树直径,而答案就是与虚树上较远的距离有关。这个可以直接拿动态开点线段树来维护。对于 \(\operatorname{lca}\) 的计算则需要 ST 表做到单次查询 \(O(1)\)。
然后先考虑直径是单点的情况。其给别的某个点带来距离的贡献。
假设当前点是 \(u\),则 \(\operatorname{dep}(u)\) 容易打全局 tag,\(\operatorname{dep}(v)\) 每个点恰好 \(m\) 份。对于 \(\operatorname{dep}(\operatorname{lca}(u,v))\),则考虑将其转化为
其中 \(w_p\) 表示和父亲的距离。特别地,根节点为 \(0\)。
那我们给 \(u\) 的所有祖先 \(p\) 加上 \(w_p\) 的贡献,那么如果询问是单点就直接链求和查询,使用带权的树剖线段树就做完了。
然而由于询问是子树,我们考虑对子树外的该部分贡献直接链查询,对子树内的该部分贡献每个点 \(p\) 只会贡献 \(\operatorname{size}(p)\) 次,使用带权的线段树直接计算即可。
然而直接可能是两个点,那我们同样分类讨论。
我们找到直径中点偏下面的那个点,令那个点子树内均以下面的点来计算贡献,否则以外面的点计算贡献,容斥一下也可以类似地拆贡献。
找直径中点的过程可以直接树剖二分,做到 \(O(\log n)\)。
使用树剖则总复杂度不会超过 \(O((n+q)\log^2n)\),使用 GBT 即为 \(O((n+q)\log n)\)。
新年的密码锁
题解
玩一下可以发现,每次一定是形如把覆盖了一条边的所有路径删除。
考虑怎么选这条边:当其两侧都有路径时,其可被选择。
显然仅对 \(\operatorname{lca}\) 往上的部分其下半边被选择了,否则即为上半边。
然后直接树剖再拿个随便什么 ds(譬如并查集)维护一下就可以快速找出每个位置什么时候开始合法。
最优解也同时拿个线段树维护一下就可以了。
总复杂度 \(O(q\log n\log q+n\log q)\)。
【UNR #5】提问系统
题解
容易发现形成树状结构,我们考虑树形 dp。
设子树 \(p\) 内同时用了不超过 \(x\) 个 R,同时用了不超过 \(y\) 个 B,此时子树内的 \(p_r^up_b^v\) 的总和为 \(f_{p,x,y,u,v}\)。
显然我们只用记录 \(x+y\le siz_p,u\le1,v\le2\) 的方案。
合并两个子树的过程可以直接对小的子树扩容,然后直接对应位置二项式展开合并,做到 \(O(\operatorname{size}(\text{大子树})^2)\)。
我们按大小顺序依次合并,再插入根的信息,容易做到 \(O(n^3)\)。
这样是过不去的,考虑优化。
我们发现,由于每个节点选法只能是两种中的一种,因此 \(c_b\) 的限制相当于变成了在每个叶子处有对链上 R 的下界的限制。
我们考虑记状态为当前节点到根为止恰有 \(k\) 个 R 的情况下子树内各种方案的贡献和,那么容易发现 dp 非常容易转移。
这样的复杂度即为 \(O(n^2)\),可以通过。
【UNR #5】获奖名单
题解
我们考虑一个节点为 \(0\sim m\) 的图,\(2\) 字符名字对应上面一条边,而单字符则对应和 \(0\) 号点的连边。
我们考虑从 \(0\) 号点开始跑欧拉回路,如果给出一组回路则给出了一组对称相消的方案。
当总长为偶数的时候,可能会出现一个孤立的自环,塞到中间即可。
当总长为奇数的时候,会无法正常跑欧拉回路,其中 \(0\) 号点度数会是奇数,而另一个度数为奇数的节点则为中间点,直接跑欧拉路径即可。
此外还可能会有多余的孤立重边,往两侧塞即可。
总复杂度 \(O(n+m)\),可以通过。
写的时候要注意一些诡异的边界问题。
【UR #22】月球铁轨
题解
月球铁轨 = 星穹铁道(不是
容易想到改定义为强制选 \(a\),而 \(a\oplus b\) 可选是否并入答案。
那么一段区间的答案仅和区间内 \(a\) 的异或和以及 \(a\oplus b\) 张成的线性基有关。
考虑对区间左端点扫描线,那么右端点对应的本质不同线性基只有 \(O(m)\) 个,其对应了若干区间。
每次插入一个元素时,我们在后面的线性基中总是会把最远一个可被代替的元素筛掉,也就对应着合并两个区间。
我们考虑对每个区间维护一个合法的 01Trie,支持子树按一定规则翻转(全部异或一个相同的数),子树内插入元素。
第一个操作直接打 tag 即可,第二个操作就是普通的 Trie 树插入。
当要往一个 Trie 对应的线性基更新的时候,我们直接暴力重构整个 Trie 即可;特别地,当要合并两个 Trie 的时候,前面一颗 Trie 的更新直接插入后面一颗 Trie 即可。
这样的复杂度可以证明不会超过 \(O(nm^2)\)。
考虑求第 \(k\) 小的答案,我们把之前的所有 Trie 都可持久化下来,然后多树二分即可。
总复杂度 \(O(nm^2)\)。
代码:这谁写啊?
【UR #23】地铁规划
题解
蛮有趣的构造题,感觉挺好想的。
我们考虑到,这种结构看上去非常需要我们把一些边“暂存”到后面某个位置,使得之后弹出前面的边时不至于要弹出一大堆边。
我们考虑假设现在处理到 \(l\),前 \(c\) 条边被我们逆序插入,其余的边按照一定顺序穿插其中。
我们考虑对每个位置 \(p<m\) 设置一个父亲 \(f_p>p\)。
我们每次要弹出 \(p\) 的时候,我们直接把到 \(f_p-1\) 的边全部弹出,然后把到 \(f_p-1\) 间-位置所有暂存的 \(>c\) 的边插回栈中,再把 \(p+1\sim f_p-1\) 逆序插回栈中。这个是 \(f_p\le c\) 的情况。
当 \(f_p>c\) 时,我们直接把当前栈弹空,然后将 \(c\) 更新至当前的 \(r\),并且把所有边逆序插入即可。
考虑怎么设置父亲。显然一种方法是直接翻转序列然后按照 BIT 的方法设置。容易证明这么做的操作次数级别为 \(O(n\log n)\) 的,并且常数超级小,可以轻松通过。
【UR #23】国王出游
题解
首先可以立刻写出答案:
看上去没有什么比较好的性质,不妨设为求
注意到这是一类可以套用拉反的经典形式。
由于 \(f(x)=e^{Ax}+e^{-Bx}-2\),我们现在假设 \(f^{(-1)}\) 为其复合逆,则另类拉格朗日反演给出
我们现在要求 \(h=f^{(-1)}\),可以直接上牛顿迭代:
但是刚刚的方法要求复合逆存在,而 \(A=B\) 时复合逆显然不存在(\([x^1]f=0\)),此时我们有
对 \(e^x-e^{-x}\) 套用同样做法即可即可。
同样方法算出 \([y^m]g(y)^j\),最后计算答案显然就是一次卷积。
总复杂度 \(O((n+m)\log(n+m)+\log v)\),但是由于牛顿迭代常数巨大(如果不同步进行并加卡常的话),实际跑起来估计并不快。
代码咕了。都 3202 年了,还有谁往 CTT 投不下发板子的多项式啊?
TBA
题解
TBA
题解
TBA
题解
TBA
题解
TBA
题解
TBA
题解
TBA
题解
TBA
题解
TBA
题解
TBA
题解
TBA
题解
【UNR #6】笔试
题解
练这套题前先刷了一中午 https://duck.ac/beibishi。
怎么笔试第一题还 AB 看反了的。/fn
答案:
A
B
B
D
C
A
D
C
C
A
C
C
C
D
D
A
B
C
D
A
D
A
B
A
D
A
D
B
C
D
C
B
B
B
B
B
A
D
A
A
D
C
D
A
B
BDF
ABF
AF
EFG
AD
A
本文来自博客园,作者:myee,转载请注明原文链接:https://www.cnblogs.com/myee/p/uoj-record.html