2024.4 做题记录
299. CF1534E Lost Array
难崩。
题意转化为每次翻转 m 个 01 序列的元素,要把全 0 翻成全 1。
不想分讨。考虑直接最短路求最小步数,转移就枚举选多少个原本已经有的数。
交互就记录方案就行了。
300. P9537 [YsOI2023] CF1764B
很棒的题。
考察终态,可以发现最后输的人拥有的数的数量大概率是比赢家的数量少的。唯一的例外是等差数列,因为一个长为 n 的等差数列只能组成 n−1 个不同的差值。
考虑若一开始先手就是一个公差为 d 的 n+1 项等差数列,后手是一个公差为 d 的 n 项等差数列,那么先手无法操作,直接寄了。
否则当先手 n+1 项后手 n 项时,最后先手输的状态一定是 d∼(n+1)d 的等差数列,后手是 d∼nd 的等差数列。要达成这个状态,充要条件是先手拿了某个 td 和 (t+1)d,同时后手拿的数 ≤td。
先手和后手初始都是 n 项时把上面的结论反过来即可。
考虑计数。可以先把先手比后手数多的情况全部加上,然后再减去等差数列的情况,再加上先手和后手的数的数量相同的方案数。
计数先手是一个公差为 d 的 n+1 项等差数列,后手是一个公差为 d 的 n 项等差数列,可以枚举公差和末项,bitset 每次与上自己左移 d 位即可。
对于另外一种,枚举 d 和 td,设 ≤td 的数的数量为 c,枚举后手的数的数量,那么这个对答案的贡献为:
容易用范德蒙德卷积化简成 (2c−1c−1)。
先手和后手都是 n 项是一样的。
那么总时间复杂度为 O(V2lnVω+VlogV),瓶颈在求第一种情况。
301. CF1056G Take Metro
逆天。
不知道为什么可以发现循环节长度很小。然后直接暴力即可,遇到循环节就直接跳过。
对于一个特定的 tmodn 考虑就不用哈希表。
实际上循环节可以证明是 O(√n) 的?
302. 2024.4.2 模拟赛 T1 度假(vacation)
没见过是真不会做。。。
显然答案的边要满足:它是全部最短路的交集,且不是全部最短路 +1 的交集。
考虑拆点,求出到每个点距离为奇数和偶数的最短路。
那么求交集就可以求最短路方案,模一些大质数即可。
303. 2024.4.2 模拟赛 T2 距离(dist)
考虑把整个网格“离散化”,缩成 O(n2) 个小矩形,每个矩形要么全是空白,要么只有一个障碍。
在新的网格上跑 O(n4) 的 BFS,就可以知道任意两个矩形的距离比曼哈顿距离大多少。
求出大多少,加上之后就相当于算两个矩形的两个点的曼哈顿距离。也可以快速算。
304. CF1942F Farmer John's Favorite Function
考虑一些复杂度带根号的做法。
考虑分块,对于一个块,我们需要处理出一个数经过这个块会变成哪个数。以下假设块长 ≥10(最后一个块块长可能 <10,暴力处理即可)。
观察这个递推式 fi=⌊√fi−1+ai⌋,发现对于一开始传进去 0 和传进去 1018,经过足够多(≥10 个,应该能更少)的数,最后得到的 fi 最多相差 1。证明显然,因为有一个根号,每次会让 Δ 开根,进行 loglogV 次 Δ 就会变成 1。
设传进去 0 得到 x,传进去 1018 得到 y。若 x=y 那么已经完成了。否则 x+1=y,我们需要求出这个分界点,即求出 z 使得传进去 z 得到 x,传进去 z+1 得到 y。考虑有 f2i≤fi−1+ai≤(fi+1)2−1,所以我们用 x 倒推,倒推的同时维护 fi 的上界即可。
修改就重构所在块,询问扫一遍所有块,维护经过一段前缀的块后的 fi 的值即可。
时间复杂度 O(n+m√n)。
305. CF1056H Detect Robots
转化:相当于要求判断是否存在 A→C→⋯→B 和 A→D→⋯→B。
根号分治。对于小路径对小路径可以枚举 B,存是否对于所有 A,后一个点都相同。
大路径对大路径、大路径对小路径,可以枚举大路径,然后扫一遍其他的路径,如果当前的点出现过,且之后出现过相同的点,且两条路径的这个点的后一个点不同,那么就寄了。
时间复杂度 O(n√n)。
306. CF1552E Colors and Intervals
只用考虑 n=k−1,相当于每个格子至多被覆盖一次。
扫序列,每次若遇到相同的元素且前面未出现过相同的这个元素那么就把它加入答案。
307. CF1552G A Serious Referee
难崩,爆搜 + 分析复杂度题。
首先转 01,相当于只用判断全部 01 序列是否都可行。
直接枚举至少也要 2n,无法承受。
发现每次排序,和最后结果有关的只有涉及到排序的元素的 0 和 1 的数量。
所以我们改变策略,每次枚举排序的元素中之前未被涉及过的所有元素中有几个 0。
分析复杂度。由基本不等式得每次未被涉及过的元素肯定越平均越好,所以最坏复杂度为 O((nk+1)k)。
308. P9039 [PA2021] Drzewo czerwono-czarne
很神奇。
考虑时光倒流,相当于每次找到两个相同的点,然后把其中一个变成 ?
。
因为 ?
的含义是之前被赋什么值都可以,所以对于一个确定的值和 ?
,我们不妨就直接让 ?
和这个值相等,然后再进行一次操作。我们惊奇地发现 ?
被交换了。
如果有 ≥3 度的点,因为若他颜色确定的儿子有 ≥3 个时(以这个点为根并且假设根被交换成了 ?
),就一定能找到两个同色的儿子,然后把它们变成问号。
这样我们发现,整棵树除了 1 和 0 和 1 个 1,其他都能变成 ?
(特判全部相等的情况)。所以此时就是一定有解。
这是存在 ≥3 度的点的情况,若不存在这样的点说明整棵树是一条链,考虑把目标状态的连续段缩成一起,那么相当于缩后的序列一定要是原序列的一个子序列。充分性和必要性都比较显然。
309. 2024.4.9 模拟赛 T2 多重序列(sequence)
板板题,很喜欢。我也就写了 23.5KB(虽然有十多 KB 的 modint
)。
显然每个序列要用一棵平衡树维护。显然不可能维护 nm 个元素,于是我们平衡树存的是形如 (cnt,x) 表示 x 这个数出现了 cnt 次。
310. P8949 [YsOI2022] 淀粉树
考虑 d=2 的部分分。相当于只用 2 次操作把 T 变成一条链。
不妨设最后变成的是一个 1∼n 的链,如果不是可以把点重编号。
第一次操作考虑以 n 为根,每次取每个儿子的子树中的最大值为新的根并和原来的根连边,这样会将整棵树具有堆的性质,即父亲的编号比儿子的编号大。
那么第二次操作时因为删完 1∼i−1 的点后 i 一定是叶子,所以合法。
实现时发现第一次操作实际上是求点权 Kruskal 重构树,从小到大加点,并查集维护每个点所在子树的根即可。
d=2 的部分分给我们启发。考虑若能让 S 逆操作 d−2 次变成一条链,那么整道题就解决了。
考虑增量法,每次把 S 中的最大度数减 1。自底向上构造,若当前点的度数为最大度数,那么就断开它和父亲的连边,在子树里面随便找一个还没标记过的叶子,将父亲和这个叶子连边,并标记这个叶子。容易归纳证明每棵子树中未被标记的叶子个数 ≥1,所以不会出现所有叶子都被标记的情况。
时间复杂度 O(ndlogn)。
311. CF1621E New School
傻逼题。
显然每次修改导致的位移是 ±1 的,所以直接前缀和判断就行了。
312. CF1621F Strange Instructions
傻逼分类讨论题。
分成开头 1,2,3 三类,以 1 开头为例,操作序列肯定形如 1212(1313(1))。然后随便算算就行。
感觉这玩意还是对着拍子一个一个调比较舒服。
313. CF1621G Weighted Increasing Subsequences
首先为了方便先把序列转成排列。
套路地,考虑计算每个位置的权值。
找到最后一个 y 使得 ay>ax(显然 y 是一个后缀最大值),那么相当于计算包含 x 的上升子序列,且结尾在 y 之前。
这个可以分成以 x 结尾的上升子序列和以 x 开头且结尾在 y 之前的上升子序列。前者容易计算,考虑后者。
考虑容斥,以 x 开头的上升子序列数量减去以 x 开头且结尾为 y 或在 y 之后的上升子序列。这里有一个观察是,结尾不可能在 y 之后(因为 y 是最后一个 ay>ax 的位置),所以只用考虑以 x 开头且结尾为 y 的上升子序列数量。
设全部后缀最大值位置从后往前是 p1,p2,…,pm,其中 y=pi。那么 ax∈(api−1,api),枚举 y 再枚举 x,相当于计算位置的上升子序列。也可以树状数组解决。
总时间复杂度就是 O(nlogn)。
314. P6700 [PA 2015 Final] Edycja
首先有两个比较显然的性质:先做操作 2 再做操作 1;每个字母只会做一次操作 2。
那么我们把每个字母向做操作 2 后变成的字母连边,会形成一棵内向基环树。边权是容易计算的。
每个点一开始先选择边权最小的出边。发现对于一个大小 >1 的纯环,只能通过外面的点中转,所以代价要 +c。所以边权最小的出边不一定是最优的。
所以考虑把环长 >1 的环拿出来,dp 每个点的出边的同时记录哪些环被破了。因为最优策略不会产生新环,所以不用考虑新环。
时间复杂度 O(n+|Σ|22|Σ|2)。
315. CF1951G Clacking Balls
考虑用相邻两个球之间的距离来描述一个状态。
设距离序列为 a1,a2,…,ak(忽略 0)。考虑鞅与停时定理,设一个状态的势能为 k∑i=1f(ai),一次操作能使得势能期望减少 1。那么:
设 g(x)=f(x+1)−f(x),有:
考虑每个数的贡献,有:
不难发现令 g(x−1)−g(x)=nmx 满足要求,因为 k∑i=1ai 恒等于 m。
若令 g(0)=0,那么 g(x)=−nm(x+12),因为我们需要在操作后删除 a 中的 0 所以必须令 f(0)=0,那么有 f(x)=−nm(x+13)。
终止状态的势能为 f(m)。于是用初始状态势能减去终止状态势能就是答案。时间复杂度 O(nlogn)(瓶颈在对每个球的位置排序)。
316. [ARC017D] ARCたんクッキー
差分,设 bi=ai−ai−1,答案是 gcd(al,bl+1,bl+2,…,br)。
317. [ABC285Ex] Avoid Square Number
直接考虑容斥,钦定 i 个完全平方数,问题变为将 Ej 分成 i 个偶数,其它 n−i 个任意即可。
尝试用生成函数刻画,方案数相当于:
这个多项式相当于 1(1+x)i(1−x)n。算出 i=0 的多项式,每次乘上 11+x=x0−x1+x2−x3+⋯ 即可。相当于做前缀差。
318. CF1613F Tree Coloring
直接拍一个容斥,现在变成划分成若干条链,使得每个点都被覆盖,容斥系数是 (−1)k,其中 k 为选的边数。设划分的链数是 c,那么方案的系数为 c!。
考虑一个点可以单独一条链或者接到任意一个儿子上,设点 u 的儿子数为 au,所以我们可以用 x−au 刻画一个点。直接分治 NTT 即可。
319. CF1758E Tick, Tock
从本质思考。。。
考虑设 ri 和 cj 分别为第 i 行和第 j 列的偏移量。试图通过计数 {rn} 和 {cm} 来计数整个矩阵。那么有一些 ri+cj=ai,j 的限制。据此可以判无解。
考虑若 ai,j 全都确定,有 h 种赋 {rn} 和 {cm} 的方案,所以答案为 hcnt−1,其中 cnt 为连通块数量。
320. CF717G Underfail
不会建图。。。
其实不用拆点,直接对一个匹配位置 i,连边 i→i+len,流量 1 费用 k。限流在一开始源点连向 1 的边进行。
321. CF1956F Nene and the Passing Game
首先若 (i,j) 满足条件就连边,则题意等价于求这个图的连通块个数。
首先直接拆绝对值,然后有二维偏序 i+li≤j−lj 和 −i−ri≤−j+rj。扫第一维的同时需要让当前点向第二维所有 bi≤bj 的点合并。
但是我们发现若某个时刻被加入的点中存在 bi≤bj 且 i,j 在同一连通块中,那么保留 i 就够了。所以每次合并的时候只保留被合并的 bi 最小的点。总时间复杂度就是 O(nlogn)。
322. CF1513F Swapping Problem
这真的不是被 CF1898D Absolute Beauty 抄袭的吗/jy/jy/jy。
考虑把绝对值看成 ai←bi 的有向线段的长度(trick++),那么发现交换一对异向的相交线段才可能产生贡献。而相交又可以分成相交但不包含或者包含。分类计算一下最大贡献,扫描线乱做即可。
323. CF1214G Feeling Good
发现只要两行的 1 位置不包含,那么一定能选出一个合法的矩形。
进一步的观察:将所有行按 1 个数排序,若有解则一定存在相邻的解。
所以用 set
维护按 1 个数排序的行即可。
324. P9139 [THUPC 2023 初赛] 喵了个喵 II
考虑若一种颜色出现 2 次怎么做。
设一种颜色出现位置为 li,ri,那么有解当且仅当 [li,ri] 不存在包含关系。构造可以直接让 li 位于第一个子序列,ri 位于第二个子序列。
出现 4 次考虑把它们分成两组,可能的分法是 (1,2),(3,4),(1,3),(2,4) 和 (1,4),(2,3)。发现最后一种一定能调整成为前面两种,所以可以忽略最后一种。
那么每个数只有两种状态了。直接跑 2-SAT 即可。可以主席树优化建图。
325. [AGC066A] Adjacent Difference
考虑黑白染色,要么黑格子变成 d 的奇倍数,白格子变成 d 的偶倍数,或者反过来。
惊奇地发现两种方案总共变化量为 dn2,输出变化量最小的那种,一定 ≤dn22。
326. [AGC066B] Decreasing Digit Sums
只用考虑 n=50。
发现我们可以用 550 搞点事情,因为 x550 的 f(2ix550) 是非常近似递增的,所以可以想到把很多 x 拼起来减少不递增的影响。
考虑随机一些 a1,a2,…,a100,把 ai550 顺次拼接(中间加个 0 避免进位影响)。很快就能跑出来(反正是个提答)。
327. Yahoo Programming Contest 2019 E Odd Subrectangles
考虑若选出了若干异或后全是 0 的行,那么选列的方案数是 0,否则是 2m−1。
所以只用将行插入线性基,查询异或后不是 0 的行的集合个数即可。
设线性基元素个数为 c,答案为 (2n−2n−c)×2m−1。
328. P7831 [CCO2021] Travelling Merchant
考虑如果是 DAG 那么可以 dp,设 fu 为点 u 的答案,那么有 fu=min(u,v,r,p)∈Emax(r,fv−p)。建反图即可。
但是有环,不能这么做。
考虑答案的上界是 maxr。启发我们按 r 从大到小枚举边,每次把这条边断开并更新 fu 为 r。然后把那些不能到达环的点全部处理掉了,剩下的点都能到达环,仍然能这么做。
329. P4238 【模板】多项式乘法逆
考虑倍增。
若已经求出 A×B′≡1(modxn),我们希望求出 B 使得 A×B≡1(modx2n)。
有:
两边同乘 A,有:
所以:
注意应该倍增到最小的 2t 使得 2t≥n。
时间复杂度 O((n+n2+n4+⋯)logn)=O(nlogn)。
330. P4512 【模板】多项式除法
比较智慧。
考虑定义一个操作 AR(x)=A(1x)=n∑i=0aixn−i。其实就是把系数翻转。
那么:
注意到 Q(x) 的最高项次数恰为 n−m,所以这样即可求得 Q(x),进而求出 R(x)。
时间复杂度 O(nlogn)。
331. P4725 【模板】多项式对数函数(多项式 ln)
考虑利用多项式求导,有:
这样就能求出 B′(x),进而求出 B(x)。
时间复杂度 O(nlogn)。
332. P4726 【模板】多项式指数函数(多项式 exp)
考虑泰勒展开。对于一个光滑函数 g(x),我们有:
考虑倍增。假设我们已经求出了 B0(x) 使得 A(x)≡lnB0(x)(modxn),我们现在希望求出 B(x) 使得 A(x)≡lnB(x)(modx2n)。那么令 g 为 ln,x 为 B(x),x0 为 B0(x)。
注意到 B(x)≡B0(x)(modxn),所以 (B(x)−B0(x))2≡0(modx2n)。所以有:
做一次 ln 和乘法即可。
注意一些实现细节,比如 ln(B0(x)) 应该在 modx2n 意义下算。
时间复杂度 O((n+n2+n4+⋯)logn)=O(nlogn)。
333. P4062 [Code+#1] Yazid 的新生舞会
考虑分治,每次计算跨过区间中点的区间的贡献。
考虑一个区间有绝对众数,当且仅当这个数在分成两半后的两半中至少有一边是绝对众数。
考虑一个序列的所有前缀,发现不同的绝对众数个数是 O(logn) 的。
然后直接找出这些绝对众数,然后枚举它们,把等于的看成 1,不等的看成 −1,做一个前缀和统计即可。
334. P4451 [国家集训队] 整数的lqp拆分
设 G 为斐波那契数列的生成函数,显然有 F=F×G+1。那么 F=11−G=1+x1−2x−x2。问题是如何展开 x1−2x−x2。
因为 11−ax=∑i≥0(ax)i,所以考虑设 x1−2x−x2=A1−ax+B1−bx=A+B−(Ab+Ba)x1−(a+b)x+abx2。对比系数后解得 A=√24,B=−√24,a=1+√2,b=1−√2。那么答案即为:
这样我们得到了求一个封闭形式的生成函数的某一次项的系数的通法。
335. P10282 [USACO24OPEN] Smaller Averages G
设 fi,j 为第一个数组分到 i,第二个数组分到 j 的方案数。
转移如果直接暴力是 O(n4) 的。考虑按顺序枚举 k,处理出前缀/后缀平均值排序数组,然后双指针前缀和优化即可。
336. P8386 [PA2021] Od deski do deski & P10375 [AHOI2024 初中组] 计数
考虑往末尾加一个元素,当前序列合法当且仅当,之前存在一个和这个元素相等的元素,使得它之前的前缀合法。
那么直接 dp,设 fi,j,0/1 为考虑了 [1,i] 的前缀,有 j 种数是之前的前缀合法,当前前缀是否合法的方案数。转移枚举当前数是否属于那 j 种数即可。
时间复杂度 O(n2)。
337. P4389 付公主的背包
设 ai 为体积为 i 的物品个数。答案的生成函数即为:
显然不能直接求。考虑先取 ln,化次方为乘。那么取 ln 后即为:
至此即可 O(mlogm) 求出 ln 后的生成函数,然后再 exp 回去即可。
338. P5273 【模板】多项式幂函数(加强版)
所以先 ln 再 exp 即可。
注意为了保证 [x0]A(x)=1 需要先提公因式 axp。
339. P5277 【模板】多项式开根(加强版)
相当于 k≡12 的快速幂。
为了保证 [x0]A(x)=1 仍然提公因数 a(因为这项一定不是 0)。那么求一个 a 的二次剩余再乘回去即可。
340. P5050 【模板】多项式多点求值
发现 F(x0)=F(x)mod(x−x0)。因为 F(x)=Q(x)G(x)+R(x),而且 G(x0)=0。
考虑分治求 F(x)modr∏i=l(x−ai)。每次把 F(x) 对 r∏i=l(x−ai) 取模即可。这样时间复杂度是 O(nlog2n),但是因为每次递归都要多项式取模所以常数很大。
发现因为余数只有常数项,并且 R(x)=F(x)−Q(x)G(x),所以我们也只用关心 F(x),G(x),Q(x) 的常数项,即 FR(x),GR(x),QR(x) 的 n−1 次项。
所以我们一开始先令 G(x)=n∏i=1(x−ai) 并算出 QR(x),然后分治左区间则乘上右半边的乘积,分治右区间则乘上左半边的乘积。并且注意到递归到 [l,r] 后之后乘的多项式次数 <r−l+1,所以可以只保留后面 r−l+1 项,这样复杂度就对了,还是 O(nlog2n)。
341. P5158 【模板】多项式快速插值
考虑拉格朗日插值,答案即为
先考虑每个 i 对应的分母 zi。设 F(x)=n∏i=1(x−xi),相当于要算 F(x)x−xi 代入 xi 后的值。但是此时分子和分母都是 0。根据洛必达法则,此时可以算 F′(x)(x−xi)′=F′(x) 代入 xi 后的值。于是多点求值即可。
再考虑算整个式子。仍然可以分治,分治的时候算 r∑i=lyizi∏l≤j≤r∧j≠i(x−xj)。只需要左边的答案乘上右半边区间多项式的乘积,加上右边的答案乘上左半边区间多项式的乘积即可。时间复杂度 O(nlog2n)。
342. UOJ182 [UR #12] a^-1 + b problem
可能也算一个套路?考虑第 j 个数第 i 个时刻能被表示成 aixj+bicixj+di 的形式,其中 xj 为第 j 个数的初值。
稍作化简可以得到每次操作后要求 F(ai),其中 F(x)=n∑i=11x+xi。考虑通分,分子相当于 n∑i=1∏j≠i(x−xj),分母相当于 n∏i=1(x−xi)。对这两个多项式分别做多点求值即可。
343. P5450 [THUPC2018] 淘米神的树
若 a,b 那么等价于树的拓扑序问题,答案即为:
考虑把 a,b 之间的链拿出来,设链长为 k,链的第 i 个点为 ai,那么一定存在一个分界点 p,使得 [1,p] 是 a 染黑的,[p+1,k] 是 b 染黑的。
不在链上的点子树大小不会变。枚举这个分界点,那么链上每个点的子树大小都知道了。乘积是一个类似于求 ∏1≤i≤k,i≠p(x−ai) 的东西,考虑洛必达法则,求导后多点求值即可。
这样有一个小问题,就是会算重。考虑枚举了 p,那么最后一个被染色的可能是 p 也可能是 p+1。那么我们就加上最后被染色的是 1 和最后被染色的是 k 的答案,然后再除 2 即可。
时间复杂度 O(nlog2n)。
344. CF115D Unambiguous Arithmetic Expression
直接区间 dp 可以做到 O(n3),卡常可过,在此就不赘述了。
为了方便先把连续的数字缩成一段。我们考虑直接从前往后扫,扫的过程中 dp。设 fi,j 为考虑了 [1,i],还有 j 个没配对的左括号的方案数。
但是我们发现我们不知道一个数字前要添加几个左括号,直接添加任意多个又会多算。
考虑我们把每个运算符的左式的括号全部去除,比如把 ((0)+(0))+((+(0))+(0))
变成 0+(0)+((+0)+0)
。发现处理后的串和原串一一对应!证明大概就是每次考虑右边管辖范围最大的一个运算符,它的左式一定是它左边的全部字符,然后递归两边还原即可。
所以我们现在就只用考虑在一个运算符后加一个左括号,或者在一个数字后加任意多个右括号。仍然用回之前的状态,fi,j 为考虑了 [1,i],还有 j 个没配对的左括号的方案数。转移容易前缀和优化。
所以时间复杂度就是 O(n2)。
345. [ARC176E] Max Vector
唉。不会网络流。
考虑最小割。考虑切糕模型。两个序列的每个值都分别建一排点表示这个值要取 ≥i。
对于第一个序列的一个元素的一排点 u1,u2,…,u500,连边 ui+1→ui,容量为 i(u501 为源点),连边 ui→ui+1,容量 ∞。割掉 ui+1→ui 的边意味着 u1,u2,…,ui 被分给了汇点,剩下的被分给了源点,表示这个值取 i。
第二个序列是类似地建图,注意边要反向。
对于一次操作,相当于 xj 和 yj 至少有一个要 ≥ai,j。所以对每个操作再建一个点 v,往两个序列的对应元素的第 ai,j 个点连容量为 ∞ 的边表示不能割,达成了至少一个 ≥ai,j 的目标。
346. CF79D Password & P3943 星空
对一段区间取反,考虑差分,相当于取反两个单点。
称关键点为差分后终态需要为 1 的点。
我们考虑这样的策略。每次解决两个关键点。可以最短路求出取反第 i 个关键点和点 j 的代价,然后因为关键点个数 ≤20 所以直接状压 dp 即可。
347. UOJ424 [集训队作业 2018] count
转笛卡尔树,相当于统计点数为 n,左拐次数 ≤m 的二叉树个数。
转多叉树,相当于统计点数为 n+1,最大深度 ≤m(根结点的深度为 0)的多叉树个数。
转括号序列,相当于统计长度为 n,前缀最大值 ≤m 的合法括号序列个数。
转折线图,相当于统计每次向右上或右下走一步,不碰到 y=m+1 或 y=−1 的折线数量。
考虑容斥,考虑枚举穿过的不合法的直线序列 aaabbbaaa… 中的子序列 abab,容易算出起点分别以这些直线对称过去的新起点。
然后就做完了。时间复杂度 O(n)。
348. P6189 [NOI Online #1 入门组] 跑步 & LOJ6268 分拆数
考虑分拆数的生成函数 n∏i=111−xi。
研究分母,相当于是互异分拆数,奇数个数被统计 −1 次,偶数个数被统计 1 次。
考虑 Ferrers 图,发现在大部分情况下互异奇数分拆数和互异偶数分拆数可以互相转换。设斜边长度为 s,底边长度为 b。发现当 b=s+1 或 b=s 且底边和斜边有公共点时才无法转换,否则可以把斜边平移到最下面,或把底平移到斜边上。
此时要么 n=s(3s−1)2 或 n=s(3s+1)2。
所以 (p0x0+p1x1+p2x2+⋯)(1+∑k≥1(−1)kxk(3k±1)2)=1,对比系数得 pn=∑k≥1(−1)k+1pn−k(3k±1)2。
直接递推即可做到 O(n√n) 计算。
349. BZOJ3028 食物
把生成函数乘起来,得到 x(1−x)4。
考虑 1(1−x)k 展开式中第 n 项的系数即为 (n+k−1k−1)。直接计算即可。
350. P6078 [CEOI2004] Sweets
差分,变成算方案的前缀和。
考虑答案的生成函数为 n∏i=11−xai+11−x1−x=1(1−x)n+1×n∏i=1(1−xai+1)。
直接 2n 枚举乘积取哪一项即可计算。
351. P6800 【模板】Chirp Z-Transform & P6828 任意模数 Chirp Z-Transform
Bluestein's Algorithm 用于当不是 2 的整数次幂时对多项式的 (I)DFT。
考虑现在要求:
Bluestein 的核心思想在于拆 mk。不难证明 mk=m(m−1)2+k(k+1)2−(m−k)(m−k−1)2。那么:
这样我们把这个东西化成了卷积形式。但是发现 m−k 可能是负数,所以需要把另外一个多项式平移 n 位再做卷积。
时间复杂度是 O((n+m)logn)。
注意到我们没有用到 w 是模意义下的单位根的特性,所以这里 w 其实可以取任意整数,所以 Bluestein's Algorithm 其实就是代入一个等比数列,然后多点求值。
注意有些博客说的 mk=12(m2+k2−(m−k)2) 有局限性,因为 w 可能没有二次剩余。
352. CF1251F Red-White Fence
考虑能用的不同长度的木板,发现出现次数为 1 时有 2x+1 的贡献,出现次数为 2 时有 x2+2x+1 的贡献(多项式次数相当于木板个数)。
直接分治乘是 O(nmlog2n) 的,会被卡。考虑把前缀按照所有前缀的端点拆成一些互不相交的区间,区间内分治乘,区间外直接乘,时间复杂度变为 O(n(m+logn)logn),可过。
353. CF1045A Last chance
其实是蠢题。
发现我们根本不用管类型 2 恰好是 0 个或 2 个的限制,因为如果最后是 1 个那么剩下两个肯定被类型 0 或类型 1 占用了,直接把它们取消即可。
类型 0 和类型 2 的构造是简单的。类型 1 考虑扫右端点,每次把一个区间最左的未覆盖点覆盖就行了。
354. UVA12633 Super Rooks on Chessboard
相当于求 x∈A∨y∈B∨x−y∈C 的点 (x,y) 数量。
容斥一下变成求交集。三个全部交起来是差卷积。其余都可以简单计算。
355. HDU4656 Evaluation
Bluestein 不是正解,因为内存很卡。
可以一次性把 f(1),f(2),…,f(P−1) 都算出来。找 P 的原根 g,变成算 f(g0),f(g1),…,f(gP−2)。
套任意模的模板即可。
356. P10084 [GDKOI2024 提高组] 计算
第一步是一个经典结论,L=mgcd(a,b)+1,R=mgcd(c,d)。
因为 L≡1(modm) 且 R≡0(modm),所以可以把问题的范围改成 [1,n=R−L+1]。
写出选数的生成函数:
我们希望求所有次数是 m 的倍数的项的系数之和。
施单位根反演:
考虑对于一个给定的 j 如何计算 F(ωjm) 即 n∏i=1(1+(ωjm)i)。
设 d=gcd(m,j)。因为有 ωkm=ωkmodmm,又因为 jd,2jd,…,njd 形成了 nmd 个模 md 的剩余系,所以:
考虑求这样一个式子:n−1∏i=0(1+ωin)。考虑分圆多项式:
代入 x=−1 得:
也就是当 md 为偶数时,F(ωjm)=0;否则 F(ωjm)=2nmd。
把 F(ωjm) 代入到答案的式子中,有:
直接计算,时间复杂度 O(Tmlogn),无法通过。
考虑一些 trivial 的优化,枚举 d=gcd(m,j),[0,m−1] 中和 m 的 gcd 为 d 的数的个数显然为 φ(md),那么:
先线性筛出全部 φ(i) 即可计算。时间复杂度降为 O(T(√m+d(m)logn)),可以通过。
357. P5293 [HNOI2019] 白兔之舞
所求即为:
接下来是一个 IDFT 的模板,直接套 Bluestein's Algorithm 即可。
358. P4191 [CTSC2010] 性能优化
循环卷积相当于直接 DFT 然后点乘起来再 IDFT 回去。
所以做 k 次循环卷积相当于每个点变成它的 k 次方。
至于如何 DFT,当然可以使用 Bluestein's Algorithm。但是也可以考虑类似 FFT 的方法,每次找到 n 的最小质因子 p,设 Fk(x)=np−1∑i=0aip+kxi,那么有 F(x)=p−1∑i=0xiFi(x),即 F(ωin)=p−1∑j=0ωijnFj(ωimodnpnp)。合并上去即可。
359. POJ2821 TN's Kingdom III - Assassination
循环卷积,直接 DFT 后除过去再 IDFT 即可。
360. P3746 [六省联考 2017] 组合数问题
相当于求 [xr]((1+x)nmod(xk−1))。直接循环卷积快速幂即可。
361. Missing Subarray Sum
有一种比较智慧的不用分讨的做法。
考虑先求出整个序列的和,然后如果我们知道 [1,n−i] 和 [1,n−i+1] 的和就能知道 an−i=ai+1 的值了。
考虑把能偏序 [1,n−i] 的区间全部删掉,也就是删掉 [1,n−i],[2,n−i],…,[i+1,n−i] 全部删掉。那么剩下的区间一定不比 [1,n−i] 大,因为对称前或对称后会被它包含。
这样增量构造就行了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!