杂题题解

loj#6694. 「MtOI2019」埋骨于弘川

观察一下给出的式子,发现答案一定是 \(2\) 的幂,直接先以 \(2\) 为底数给所有数取对数,然后 \(x=0\) 的时候是做线性递推, \(x\) 每加 \(1\) 相当于对上一列做了一次前缀和,于是只需要先假设 \(f_0=-1\) ,对 \(f\)\(k\) 阶差分即可求出现有递推式,接着就是常系数线性递推板题。

以上操作均需要 Mtt
code


Codechef A Leisurely Journey

观察一下发现是线性递推裸题,然后上 mtt 的多项式取模

用上面的做法貌似不仅会超时还会爆精度, sad...

由于这是一个线性递推,我们设 \(F(x)\) 表示走到 \(n\) 点的生成函数,显然 \(F(x)\) 可以写成 \(\frac{P(x)}{Q(x)}\) 的形式,考虑转移容易知道 \(Q(x)=\prod\limits_{i=1}^n(1-L_ix)\) ,那么结合 \(C-H\) 定理我们每次只用求 \(x^t\mod (\prod\limits_{i=1}^m(x-L_i))\) ,但是 \(n\log n\log t\) 的时间开销太大了,不妨研究一下 \(Q(x)\) 的性质来优化。
冷静一下发现可以把取模的式子改写成 \(\prod\limits_{i=1}^m(x-L_i)^{k_i}\) ,满足 \(\forall i\not=j,L_i\not=L_j\) .

由于 \((x-L_i)^{k_i}\)\((x-L_j)^{k_j}\) 是互质的,所以可以考虑分别求 \(x^t\mod (x-L_i)^{k_i}\) 然后 \(CRT\) 起来。

先考虑求 \(f(x)=x^t\mod (x-L)^K\) ,考虑设 \(g(x-k)=f(x),g(x)=(x+k)^t\mod x^K\) ,那么如果知道 \(g\) 的每个位置会对答案产生多少的贡献,可以逆推出 \(f\) 的每个位置对答案产生的贡献。

然后考虑求 \(CRT\) 的系数,即令 \(M'(x)=\frac{M(x)}{(x-L)^K},coe=M'(x)*(M'(x),(x-L)^K)^{-1}\) ,前面可以直接搞,考虑怎么弄后面的.
设后面的多项式为 \(H(x)\) ,那么 \(M'(x)*H(x)\equiv 1\mod (x-L)^K\) ,我们先利用 \(M'(x+L)\) 在模 \(x^K\) 的意义下求逆然后用得到的 \(H(x+L)\) 还原 \(H(x)\) 即可。

code


某模拟题

有一个长度为 \(n\) 的序列,以及一个长度 \(m\)\(q\) 次询问,每次查询给一个查询 \([l,r,v]\)\(i\) 点的答案是 \([i,i+m-1]\) 中比 \(v\) 小的值的个数,问区间 \([l,r]\) 中最小的答案,强制在线,空间复杂度要求 \(O(n)\) 级别,此问题中 \(n,m,q\) 可视为同阶.

首先观察问题的本质,发现是在二维平面上支持加法和询问最小值,可以用主席树得到一个时空 \(O(n\log n)\) 的做法,然后好像可以压空间过题

观察这个二维平面,发现有一维是按照每个 \(a_i\) 产生贡献的时间,另一维是位置的下标,考虑对下标那一维进行分块.

然后观察 \(a_i\) 对序列的贡献,发现 \(a_i\) 的影响是一段区间,考虑把影响用差分的形式表示出来,那么就是 \(++\Delta_{\max\{0,i-m+1\}},--\Delta_{i+1}\) ,这时候的答案可以转化为求这个差分数组在一段区间的前缀和最大值,如果能够快速求出在询问对应的修改时间点每个块的和和每个块的前缀最大值,以及能够 \(O(1)\) 递推的话就可以在 \(O(n\sqrt n)\) 的时间内求出答案。
那么冷静一下可以知道除了 \(0,n+1\) 这两个位置以外其余位置最多被修改两次,也就是说每个块的和和每个块的前缀最大值只会变化 \(O(\sqrt n)\) 次,容易想到把每个块每次修改后的值给存下来,这样只需要知道每个块在询问的时候对应的修改时间点就可快速得出其整块和和整块前缀最大值。
怎么快速求每个块的修改时间点呢?
我们考虑分段打表的做法,预处理出 \(k\sqrt n(k=0,1,...,\sqrt n)\) 时候每个块的修改时间点,然后每次询问只需要 \(O(\sqrt n)\) 的时间就可以求出当前每个块的修改时间点,
现在还剩一个问题,如何 \(O(1)\) 递推,再冷静一下可以发现从 \(i\Rightarrow i+1\) 就是考虑 \([a_i<v],[a_{i+m}<v]\) 这两个的贡献。至此,已经可以在 \(O(n\sqrt n)\) 的时间内完成该问题。

code


loj#6609. 无意识的石子堆 加强版

首先容易发现性质,每行一定会摆两个,不难想到把那一行摆上的石子的两列连一条边。
然后相当于列是点集,行是边集,构成的图的每个连通块可以是一个孤点,或者点数 \(\ge2\) 的链或者环,现在要求的就是所有 \(m\) 个点 \(n\) 条边且点和边都带标号的图的个数。
由于 \(m\) 比较大,考虑从 \(n\) 的角度下手,先抛开所有的孤点,然后考虑剩下 \(m'\) 个点 \(n\) 条边的图的方案数.
冷静一下发现 \(m'-n=链的数量\) ,且 \(m'-n\le n\) ,因此容易想到枚举链的数量来统计答案,我们设链关于点的 \(EGF\)\(F_1(x)\) ,环关于点的生成函数是 \(F_2(x)\) ,且这两个 \(EGF\) 同时包含了点和边标号的信息,那么有:

\[\begin{aligned} F_1(x)=&\sum\limits_{i\ge2}\frac12x^i\\ F_2(x)=&\sum\limits_{i\ge2}\frac1{2i}x^i\\ Ans=&\sum\limits_{i=0}^{n}n!*(n+i)!*[x^{n+i}](\frac{F_1(x)^i}{i!}e^F_2(x))*C_m^{n+i}\\ =&n!m^{\underline n}[x^n](e^{F_2(x)}*(\sum\limits_{i=0}^n\frac{(\frac{F_1(x)}x)^i}{i!}*(m-n)^{\underline i}))\\ e^{F_2(x)} 直接多项式 exp&只能过掉非加强版,考虑用 dp 叙述 exp 的过程就是一个简单递推问题,这里不说了\\ 然后设 G(x)=&\sum\limits_{i=0}^n\frac{(\frac{F_1(x)}x)^i}{i!}*(m-n)^{\underline i}\\ \frac{F_1(x)}{x}=&\frac{x}{2(1-x)}\Rightarrow G_t=\sum\limits_{i=0}^nC_{t-1}^{i-1}\frac1{2^i}(m-n)^{\underline i}\\ 做一次卷积&预处理出 G(x) 即可 \end{aligned} \]

code


loj#2870. 「USACO 2018 US Open Platinum」Train Tracking

注意到给出的存储空间有限,范围很分块,于是考虑按着出题人的意思来编分块做法。
对于这个滑动窗口的问题有一个单调队列的经典做法,直接做会爆给定的存储空间,因此要进行一些预处理来优化。
考虑在第一轮的时候预处理出 \([i*B,i*B+K)\) 区间中最小值的位置 \(f_i\) ,然后在第二轮进行询问。
然后第二轮的时候每个数放进单调队列的时候由于处理出了 \(f_i\) 所以多出一个限制:假设当前询问 \(i*B+j,0\le j<B\) 的答案,那么只需要放入下标范围 \([i*B,(i+1)*B)\) 的数。
这样空间就摊成了 \(O(\sqrt n)\) 级别的。
code


loj#6668. 「XXOI 2019」三个愿望一次满足

考虑设 \(F_t(x)=\prod\limits_{i=1}^t(2ix-1),G_t(x)\sum\limits_{i=0}^tF_i(x)\) ,由于 \(x^{32}\) 及更高次项的系数模 \(2^{32}\)\(0\) ,所以可以看做次数为 \(31\) 的多项式,容易发现这两个玩意儿都可以倍增,因此我们现在已经可以快速求 \(F_i(x)\) 的区间和了。
然后考虑按数位分组算一算即可,复杂度是 \(O(poly(\log))\) 的。
code


keyence2020F Monochromization

容易想到从时间倒流的角度来考虑问题。
考虑被刷上的最后一行/列在刷完之后一定是同色的,那么如果不考虑这次操作,之前这行/列上的格子被染成啥色都无所谓,所以等价于直接把它删掉。
删成空矩阵或者删不动说明到了一个合法的初始情况,可以对答案产生 1 的贡献,对这个东西计数就 win 了😁
思考过每轮同时删行列但没有编出来细节,所以后面把想法改成了每轮只删掉行/列。
容易发现除了第一次删,如果我们在当前轮只删掉一种颜色,那么在这之后每次都会删掉和上一轮相反的颜色。
然后状态就比较显然了,定义 \(H/L_{i,j,0/1}\) 表示上一轮删掉的是行/列,现在剩 \(i\)\(j\) 列,上一次删掉了 \(1/2\) 种颜色的方案数。
转移也比较显然,这里不说了。
关键是初始化不好搞,听孙队长讲了一下发现可以假装有第 \(0\) 次删除操作,并且删掉的是列,这样的话需要给 \(L_{n,i,1}\) 初始化。
注意如果最后删不动的话方案数要除一个组合数,因为我们并不需要分配这些位置。
code


[AGC025E] Walking on a Tree

容易发现答案的上界是 \(\sum\limits_{(u,v)\in E}(2,该边被覆盖次数)\),下面给出一个能达到上界的构造方法。
所以最优化问题变成了构造最值问题,感觉有毒
每次找一个叶子 \(x\) 出来,如果它和它父亲 \(u\) 之间连上的边被覆盖了不超过 \(2\) 次,就可以瞎定向,假设有一条 \((v,x)\) ,我们把它改成 \((v,u)\) 然后删掉这个叶子即可。
如果覆盖了两次及以上,我们每两条扯出来搞成相反的方向,这样保证了边 \((u,x)\) 的答案是 \(2\) ,然后假如有路径 \((a,x),(b,x)\) ,把它改成 \((a,b)\) 即可。
code


[AGC044E] Random Pawn

容易发现如果走到最大值会直接结束,所以可以做一个等价的转化:直接从最大值那个地方把环断开成链,看成首尾都是最大值。
然后有个转移是 \(E_i=\max\{A_i,\frac{E_{i-1}+E_{i+1}}{2}-B_i\}\)
这个形式不好观察,考虑搞一个 \(C\) 把后面的 \(B_i\) 给消掉,形成一个新的形式: \(F_i=\max\{D_i,\frac{F_{i-1}+F_{i+1}}2\}\)
这个东西求和就是由 \((i,F_i)\) 构成的凸包包住的整点数量,统计一下再去掉 \(C\) 的影响即可。
code


[CF886F]Symmetric Projections

首先换个方式理解题意。
我们看一下发现投影到 \(x\) 轴上面就是取它们的横坐标,现在考虑如何投影到过原点的其余直线,发现等价于把所有点转一个角度然后取横坐标。
也就是枚举一个角 \(\theta\) \((x_i,y_i)\rightarrow(x_i*\cos\theta-y_i*\sin\theta,x_i*\sin\theta+y_i*\cos\theta)\) ,我们要看 \((x_i*\cos\theta-y_i*\sin\theta,0)\) 是否存在对称中心。
这个怎么搞呢,注意到如果存在对称中心,它一定是 \((\frac{\sum\limits_{i=1}^nx_i}{n}\cos\theta-\frac{\sum\limits_{i=1}^ny_i}{n}\sin\theta,0)\).
考虑暴力点对算直线的斜率,这样只有除去一定合法的点外被计算等于 \(\lfloor\frac{n'}2\rfloor\) 次的可能合法,暴力检验一下即可。
code


[AGC029F]Construction of a tree

首先考虑把点和点集拿来建二分图。
然后我的思考重心转移到了通过网络流构造限制来跑出合法解,但没法处理不连通的状况。
这个时候发现可以使用 \(hall\) 定理,但是我不是很会把 \(hall\) 定理套到建图上,然后听 \(scb\) 讲了一下标算,发现...
直接抠掉一个点做最大匹配,然后用抠掉的点来构造生成树即可...
证明挺容易的,不写了。
code


[AGC040E]Prefix Suffix Addition

考虑一定可以把第一种操作的操作区间拆成不相交的,第二种同理。
然后我咸掉了
然后你发现可以暴力 \(dp\),就做完了。
code


[gym102028G]Shortest Paths on Random Forests

显然期望等于总贡献除以方案数。
方案数是带标号森林树,拿个树的生成函数去 \(\exp\) 一下就行了。
考虑怎么求总贡献。
首先求一下所有方案两两可达的点对数之和,\(C_n^2\) 乘上带标号森林数减去这个东西就是 \(m^2\) 被计算的次数。
然后就只需要考虑带标号树的路径长度平方和,这个随便组合意义一下即可。
code

posted @ 2020-04-19 00:39  soroboruo  阅读(434)  评论(0编辑  收藏  举报