12月杂题选做
杂七杂八算法学了一些,记录一下。
P2483 \(\color{Gold}\bigstar\)
\(k\) 短路板子。
还是很高妙的,先跑出一棵最短路径树,那么一条从 \(1\) 到 \(n\) 的路径一定可以分成树边和非树边,那么一条非树边增加的最短路是固定的。
那么把一个点的所有非树边方案放到一个堆里,每次取出最小值然后走过去,或者不选这条边那么就选堆的左右子树即可。
可以用可持久化可并堆维护一下。
P4102 \(\color{green}\bigstar\)
走恰好若干步显然是一个矩阵乘法。
算个前缀和,可以分治递归,每次算出 \(\le K/2\) 的矩阵即可。
P5288 \(\color{blue}\bigstar\)
感觉不是很难。
容易发现最后一定是一个 \(n\) 为根的菊花,第一问的答案显然就是有多少条线段没有 \(n\)。
第二问,把三角剖分树建出,答案就是树的拓扑序数量。
考虑修改,放在树上就是一个左旋或者右旋操作,直接维护。
qoj7932 \(\color{Gold}\bigstar\)
困难题啊。
考虑一个必要条件,两个位如果满足出现位置严格包含了,那么显然一个选了另外一个必须选,这样得到一个 dag,必要条件就是选一个 dag 的前缀。
然后瞎证明一下发现也是充分的。
就是考虑归纳,每次 dag 在一个已有的前缀状态下加入一个点,那么先把这个点对应的序列中的数全部与一下,再和已有的那个状态或一下即可。
那么变成求 dag 割的数量,meet in the middle 一下,先预处理一个点需要选的前置点,然后注意到把一边选的点以及他们在另一边对应的前置点去掉之后,就变成只需要在右边选满足右边条件的点即可,这个可以先预处理即可。
P5417 \(\color{Gold}\bigstar\)
原先做过,现在忘了。
一个排列是后缀数组需要满足的条件就是如果相邻两个要么不等,要么相等那么就去比后面一个。
这个比后面一个这个条件非常难做,想半天不会,事实上完全不用这个条件。
考虑一个 \(\sum c_i=n\) 的情况,稍微想一下就可以发现,把若干个位置放入一个字符,此时对应唯一的一个后缀数组(产生的字符串都相同)。
也就是说,此时的答案是 \(\binom{n}{c_1,c_2,...,c_m}\)。
注意到一个后缀数组对应一个不等式链,也就是每个位置和后面一个位置都是 \(<\) 或者 $\le \(,\)<$ 的位置需要钦定前后字符不同,$\le $ 随意,容易发现一个后缀数组对应一个唯一的不等式链。
然后拿一个不等式链来考虑,相当于选若干个位置放到两个 \(<\) 中间,那么此时一种放法还是可以看成是一种字符串,因为两个 \(<\) 中间的字符可以看成全部相等。
总结就是:字符串推出唯一的后缀数组,后缀数组和不等式链双射,然后现在用不等式链推出字符串。
把一段 $\le $ 的看成相同的得到方案,接下来的问题是 \(<\) 是没有被限制的,也就是可以变成 $\le $。
然后就是经典容斥,改一个加一个 \(-1\) 的系数即可。
P4500 \(\color{red}\bigstar\)
这是真的,屁也不会,群论推半天感觉没啥用。
参考link,做了一定的补充(?
注意题目同构的定义是有根的。
首先注意到本质是要求
然后注意到每个轨道可以表示为一棵无标号有根树,用 \(T\) 来代替轨道 \(x\),然后令 \(f(T)\) 表示与 \(T\) 同构的方案数,也就是 \(|x|\)。
直接瞎数一下,可以得到:
后面的 \(w\) 是因为 \(u\) 的两个儿子的子树可能同构,需要去掉。
这样有一个好处是式子是乘法而不是加法,取 \(k\) 次方非常方便。
反手设一个 \(dp_{n,m}=\sum_{|T|=n}f^m(T)\),然后去求。
换用一个求无标号树的套路,把根拿出,然后它的子树相当于一个背包。
注意到这个式子有点引荐了,不妨换一下 \(f\) 的定义,修改为:
\(dp,\text{Ans}\) 也同理修改。
把后面东西拉出来:
\(\ln\) 里面东西无法做,但是我们可以去把 \((f^m(T)x^{|T|})\) 换元一下,然后求出这个 \(\ln\) 会在前面乘上的系数,本质上就是多项式复合的定义,但是需要满足 \(\ln\) 有常数项。
可以这么做的本质是,多项式 \(\ln\) 是泰勒展开,因此相当于每一项去卷上 \(\ln x\) 的展开式。
设:
好处是这个东西只和 \(m\) 有关,可以暴力预处理。
现在回想一下我们咋能求出答案,显然是要对 \(dp\) 进行递推,也就是我们需要知道 \(dp\) 的递推式即可。
注意到上下两个东西在后面那个地方是很像的,但是下面是 \(f^{mj}(T)\),考虑修改 \(dp\) 的定义使得可以适应这个东西。
令
\(k\) 是题意中选 \(k\) 棵树。
由于只是把 \(m\) 换成了 \(mk\),因此直接可以得到对于新的 \(dp\):
最后要求的就是 \(dp_{n,1}\)。
注意到后面有一个 \(x^{ij}\),也就是 \(ij<n\)(此处是 \(dp\) 下标里的 \(n\)),那么 \(j<n/i\),容易证明对于可能对答案有贡献的 \(dp_{i,j}\) 满足 \(ij\le n\)。
终于有做法了,就是考虑记录对于每个 \(m\) 的前缀卷积,然后正常做就行。
最后的问题是 \(O(n^2)\) 的多项式 \(\exp,\ln\)。
下面式子两边求导:
然后就可以做了。
像这种数数题,lg 题解中很多直接给出修改定义后的 \(dp\) 有点离谱了,感觉就是为了讲做法而讲做法,导致像我这样不会做的人完全无法理解思考过程啊。
事实上关键性的步骤是:拆成子树的背包,用 \(B\) 代换掉 \(\ln\),以及重新设计 \(dp\) 意义。
P4339 \(\color{red}\bigstar\)
不会,有时间补。
qoj2601 \(\color{Gold}\bigstar\)
好题,就是代码单薄了一点。
注意题意是 \(\sum a_i+\prod a_i\equiv s \pmod n\)。
答案 \(\bmod q\) 显然有用,考虑一些抵消。
对于一个集合 \(a_1,a_2,...,a_q\),考虑它能生成所有序列的和来发现一些性质。
但是考虑这个比校困难,主要是因为数可能会有重复,贡献很难拆开,因此换成求 \(a\) 所有排列(不保证本质不同)的和,最后再去除掉 \(\prod \frac{1}{(c_i)!}\)。
那么现在变成 \(a_i\) 数值可能相同,但是我都看成了不同。
但是注意这里如果所有 \(a_i\) 相同,是不能除以 \(p!\) 的,所以要把这种情况扔掉,最后考虑。
考虑左边的 \(\prod_{i=1}^q (a_i+i)\),暴力一拆,相当于一个 \(a\) 的子序列去乘以一个引荐东西。
分析一下这个引荐东西,就是 \([1,q]\) 里面选 \(k\) 个数乘积的和。就是
考虑一下 \(\prod_{i=1}^q (x+i)\) 是啥,注意此处 \(q\) 是质数。
瞎枚举几个 \(q\) 发现中间项都没了。
只会对着结论证明了,结论就是 \(\prod_{i=1}^q (x+i)=x^q-x\),是把系数对 \(q\) 取模意义下。
证明考虑类似费马小定理的证明,取一个正整数 \(a\)。
这个是因为模 \(q\) 下 \(ia\) 与 \(i\) 一一对应。
然后暴力拆开每一项,发现 \(x^k\) 右边式子多了一个 \(a^{q-k}\),因此除非 \(k=1,q\),否则右边会出现 \(c_i=a^{q-k}c_i\) 的情况,也就是系数都是 \(0\)。
然后单独考虑剩余的两项,一个是全部选,一个是只选一个。
考虑全部选部分,每个排列显然答案相同,本质就是:
右边部分就是 \(-\sum a_i(p-1)!=\sum a_i\)。
然后再去考虑 \(\sum_{i=1}^q 2^{i-1}a_i\) 这个部分。
单独考虑每一个的贡献,得到:
和前面抵消。
也就是说,如果 \(a_i\) 不是全部相同,对答案无贡献。
那么枚举 \(a_i\) 即可,复杂度 \(O(q\log n)\)。