1. Figures
注意到存在度数限制所以考虑 prufer 序列。
考虑生成函数,即考虑单个元素 \(i\),若在 prufer 序列出现 \(k\) 次则方案数是 \(d_i^{\underline{k+1} }\)(这里不是组合数,因为孔是可区分的)。
碰到这类多个元素的合并问题常用 egf:即设 \(F_{i}(z)=\sum\limits_{k= 0}^{d_i-1}\frac{d_i^{\underline{k+1} }}{k!}z^k\),然后有 \(F(z)=\prod_{i=1}^{n}F_i(z)\),则 \((n-2)![z^{n-2}]F(z)\) 即为答案。
观察到 \(F_i(z)\) 的系数其实极为接近组合数。根据 \(x^{\underline{k}}=x(x-1)^{\underline{k-1}}\) 可以得到 \(F_i(z)=d_i(z+1)^{d_i-1}\)。
所以不妨设 \(F_i(z)=(z+1)^{d_i-1}\) 而 \(F(z)\) 依旧是它们的卷积结果。则答案为 \((\prod_{i=1}^{n}d_i)(n-2)![z^{n-2}]F(z)\)。
而 \(F(z)\) 实质上是 \((z+1)^{s}\),这里 \(s=\sum_{i=1}^{n}(d_i-1)\)。
所以 \([z^{n-2}]F(z)=\dbinom{s}{n-2}\)。
所以 \(ans=(\prod_{i=1}^{n}d_i)(n-2)!\dbinom{s}{n-2}\)。
观察到 \(s\lt n-2\) 的时候答案为 \(0\),否则 \(\dbinom{s}{n-2}=\frac{s^{\underline{n-2}}}{(n-2)!}\),所以答案化简为 \(s^{\underline{n-2}}\times \prod_{i=1}^{n}d_i\)。
时间复杂度 \(O(n)\)。
2. Neq Neq
容易发现如果 \(a_{i}=a_{i+1}\) 则可以把序列在此处分段。所以我们仅用考虑没有两个相邻数相等的情况。
这种情况是友好的,因为我们至少在第一步总能消去一个数。但是我们发现并不总是这样:\(\text{12121212}\) 就是反例。
容易证明只出现两种数字的时候形如 \(\text{121}\) 是唯一友好的(友好指最后可以把除了两边端点的以外的都消去)。而似乎只要有三种不同数字就一定是友好的。
证明分为两部分:1. 证明此时总能找到 \(i\) 使得 \(a_i,a_{i+1},a_{i+2}\) 互不相同。尝试构造不满足这样的串,发现只能是 \(\text{121212}\) 类型的。所以此时若三种字符都出现超过一次,我们找这个 \(i\) 消去即可。
- 当有一个字符只出现一次的时候,不妨设它在中间,则两边都形如 \(\text{abababab...c}\),由于 \(c\) 不再出现,所以左边必能消尽,对于右边同理,则最后消去 \(c\) 即可。而 \(c\) 在两侧的情况同理。
然后简单 dp 即可。
3. Mark and the Online Exam
考虑如果初始询问一次,则之后的操作实质上变成了给出一个子集去询问匹配个数。
另外观察到这个上界略大于 \(\frac{2}{3}\),这启发我们对三个数去寻找两次询问的做法。
考虑 \(i,i+1,i+2\) 三个位置。询问 \(i,i+1,i+2\) 一次,询问 \(i,i+1\) 一次。当且仅当 \(i\) 和 \(i+1\) 不同的时候我们不能确定做法。
牛逼的是考虑基于 \(\text{TFTFTF...}\) 这个串去询问 \(i,i+1,i+2\),基于 \(\text{TTTTT...}\) 这个串去询问 \(i,i+1\),则 \(i\) 和 \(i+1\) 不同的四种情况可以被唯一确定。
4. DFS Trees
众所周知最小生成树边权构成的多重集唯一。本题由于是排列所以这个结论等价于最小生成树唯一。
所以变成了问以某个点为根的 dfs 树是否走的都是一个最小生成树的边。最小生成树的特性使得非树边的边权一定合法(非树边 \((u,v)\) 一定大于 \(u-v\) 上边权最小的那个)。所以我们只要让横叉边不出现即可。(因为 dfs 树中不存在横叉边,只存在树边以及返祖边。)
以 \(1\) 为根 dfs 最小生成树,我们将看到,每条非树边会对答案造成一定限制。
-
横叉边 \((u,v)\),则只有 \(subtree(u),subtree(v)\) (包括 \(u,v\))可以作为根。
-
返祖边 \((u,v)(depth_u\gt depth_v)\),则只有 \(subtree(u)\),以及 \(Tree-subtree(v)\)(包括 \(u,v\))可以作为根。
两种限制本质上都可以看作子树加/减。可以 dfs 序上用 bit 维护。但是因为是离线所以直接树上差分打 tag 即可。
时间复杂度 \(O(n\log n)\)。
5. Partial Virtual Trees
注意到题目等价于给除了点 \(1\) 以外的所有点打tag:tag即为在哪次操作中第一次被删除。
设 \(max(u)\) 是 \(u\) 子树内的最大 tag,则必须满足 \(u\) 的 \(tag\) 大于等于子树中,\(max(v)\) 次大的值(否则说明 \(u\) 删除的时候还有至少两个子树有点,这样 \(u\) 就不能删除)。
有了这个性质以后尝试 dp:设 \(f(u,k)\) 是子树 \(u\),标号范围钦定在 \([1,k]\) 的方案数。
发现这样不好转移,不妨设 \(f(u,k)\) 为标号钦定在 \([1,k]\) 且强制让 \(max(u)=k\) 的方案数。这样我们可以在 \(n^3\) 的时间内计算出所有的 \(f\)。具体而言:观察到只有两种情况:
-
\(tag_u=k\),则 \(f(u,k)=\prod_{v}f(v,k'\le k)\)。
-
\(tag_u\lt k\),设其为 \(a\),则 \(f(u,k)\) 会加上 \(\sum_{v_1}f(v_1,k)\prod_{v\neq v_k}f(v,k'\le a)\)。
注意到 \(f(v,k'\le k)\) 这种东西可以用前缀和预处理,设为 \(g(v,k)\)。然后第一种情况就变成 \(O(n^2)\) 的了。但是第二种情况要枚举 \(v_1\),还是太慢了。注意到我们把 \(g(v,a)\) 的乘积预处理出来设为 \(mult\),则实际上是这样一个贡献过程:\(mult(a)\times g(v_1,a)^{-1}\times dp(v_1,b)\rightarrow dp(u,b)\),这里只要 \(a\lt b\) 都会产生贡献。所以我们直接枚举 \(b\),然后此时把 \(mult(a)\times g(v_1,a)^{-1}\) 再求一下前缀和即可。由于有逆元的缘故所以复杂度为 \(O(n^2 \log n)\),若实现不精细依旧不能通过。比较极限的手法是把 \(mult(a)\) 拆成前后缀两段,这样直接把前后缀两段相乘即可,就不用求逆元了,这个做法是严格 \(O(n^2)\) 的且不依赖模数是质数的限制。
此时依旧没有得到答案:因为题目告诉我们,\(1\sim k\) 必须在 \(tag\) 里都出现。我们现在求的 \(F(k)\) 只保证了最大 \(tag=k\) 一定出现,而 \(\lt k\) 的值不一定出现。
设 \(G(k)\) 是 \(1\sim k\) 都出现的标号方案数,则有:
观察到这个形式非常接近二项式反演。设法让组合数变成 \(\dbinom{i}{j}\),不难发现:
用 \(f(i)=F(i+1)\) 和 \(g(i)=G(i+1)\) 进行替换,然后得到:
这就是标准的二项式反演了:
在 \(O(n^2)\) 的时间内求出了所有的 \(g\),也就等于求出了所有的 \(G\),即所有答案。
\(i+j=i\and j+i\or j\) 可以从集合角度加以出发理解。然后有 \(f(2^i)+f(2^j)=f(2^{i}+2^{j})+f(0)\)。如果两边同时减去 \(2f(0)\) 就会发现一个极其优美的 \(g\) 存在:\(g(2^i)+g(2^j)=g(2^{i+j})\)。
所以如果确定了 \(f(0),g(1),g(2),...,g(2^{n-1})\) 我们就唯一确定了整个序列,这 \(n+1\) 个数里 \(f(0)\) 是特殊的啊。
注意到把 \(f(mask)\) 进行二进制分解,则实质上有:\(f(mask)=\sum_{i\in mask}g(i)+g(0)\) 啊。
但是 \(g\) 的取值是整数域。为了让 \(0\le f\le k\) 的目标成立,显然我们只研究 \(f\) 的最小值和最大值。即设 \(s_1\) 是 \(g(1)\sim g(2^{n-1})\) 里全体负数和,而 \(s_2\) 是全体正数和,则有 \(g(0)+s1\ge 0\) 以及 \(g(0)+s2\le k\),那么贡献是 \(\max\{0,k+1-g(0)-(s2-s1)\}\)。而 \(s2-s1\) 就是 \(g(1)\sim g(2^{n-1})\) 的绝对值的和啊。
所以我们大概需要确定符号(那么这里就要特殊考虑 \(0\)),但是还有一个问题是那个 \((k+1)-sum\) 的系数存在。一个套路是此时再加两个非负变量进去,这样如果前面余下 \(a\) 后面就会有 \(a+1\) 种选择,最后特判后面两个都填 \(0\) 这种多判的选择就行了。
然后可以推出式子:\(ans=\sum_{i=0}^{n}2^{i}\dbinom{n}{i}\dbinom{k+1}{i+1}\)。
另外还有一种生成函数出发的推法:
万物皆可生成函数啊,一个数如果最后绝对值取了正数贡献为 \(2\),否则为 \(1\),否则有生成函数 \(f(z)=1+2z+2z^2+...+2z^n+...=\frac{1+z}{1-z}\)。\(n\) 个卷起来就是 \(F(z)=(\frac{1+z}{1-z})^n\)。然后考虑 \([z^a]F(z)\) 的贡献是 \((k+1-a)\),如果是组合角度,则我们很难想到上面特殊的插板法;从生成函数角度来看,由于 \(a+k+1-a\) 恒为 \(k+1\),这无非就是加了一个卷积进去:求 \([z^{k+1}]F(z)G(z)\),其中 \(G(z)=z+2z^2+...+nz^n+...=\frac{z}{(1-z)^2}\),所以求的是 \([z^{k+1}]\frac{z\times (1+z)^n}{(1-z)^{n+2}}\),分子分母都可以用二项式定理展开,最后分别得到:\(\sum_{i=0}^{\infty}\dbinom{n}{i-1}z_i\) 以及 \(\sum_{i=0}^{\infty}\dbinom{n+i+1}{i}z^i\),对其求第 \(k+1\) 项系数,即为:\(\sum_{i=0}^{n}\dbinom{n}{i}\dbinom{k+n-i+1}{k-i}=\sum_{i=0}^{n}\dbinom{n}{i}\dbinom{k+n-i+1}{n+1}\)。
这下真的变纯纯的 GF 了。
首先一个容易想到的转化是:我们计数 \(p_i\),其中 \(p_i\) 是恰好有 \(k\) 个相邻不同颜色的排列数。通过 \(p_i\) 求 \(f\)(这一步求法是一个类似科技的东西,是一个较硬伤的东西啊。)我们先假设这总是可行的。
我们发现直接求 \(p\) 仍然存在一定困难。首先不妨转成求相邻的相同颜色个数,这显然好做。发现一个诱人的想法:对每种颜色分别求出某些东西,将其的 \(egf\) 直接卷起来即可。容易发现相邻不同颜色数直接和分出来的极长颜色段数量有关,更为具体的,设有 \(k\) 个极长同色段,则相邻的相同颜色对数为 \(n-k\) 对。这启发我们转为求颜色段数。
设颜色 \(i\) 出现了 \(cnt_i\) 次。
首先我们忽略标号,在算完 \(p\) 以后将 \(p\) 乘上 \(\prod cnt_i!\) 即可。那么分 \(k\) 段的方案数是自然的:\(\dbinom{cnt_i-1}{k_i-1}\)(这里要特判 \(cnt_i=0\) 的情况)。所以我们有一个 \(egf:f_i(z)=\sum_{k=1}^{cnt_i}\dbinom{cnt_i-1}{k-1}\frac{z^k}{k!}\)。卷起来得到一个 \(F(z)\)。显然这些多项式的次数总和是 \(n\),所以可以利用分治 + NTT 在 \(O(n\log^2 n)\) 的时间内算出 \(F(z)\) 的各项系数(另一个办法是启发式合并:每次找次数最小的两个多项式,卷起来)。但是 \([z^i]F(z)\) 并不是 \(p_{n-i}\)。因为我们的 egf 在进行组合的时候并不能保证同色段不会被组合到一起。实质上设 \(q_{n-i}=[z^i]F(z)\),则 \(q_i\) 的意思是至少 \(i\) 个相邻相同颜色的排列数。那么显然存在一个二项式反演的关系:
有趣的是这里也存在一个科技:可以一次卷积求出 \(p_{1\sim n}\)。首先,我们把组合数拆开:
我们令 \(G(i)=\frac{(-1)^{i}}{i!},H(i)=i!q_i\),则有
现在我们只来研究后面的 \(\sum\)。对和式做变换得到
这是一个标准的差卷积 形式。通过把 \(H\) 反转:\(H'(i)=H(n-1-i)\),我们将看到:
此时变成了一个和卷积,指数下标和固定为 \(n-1-i\)。这种处理差卷积的方法也是一个常见的套路。
现在我们已经求出了 \(p\),最后的任务是通过 \(p\) 还原 \(F\)。我们知道:
通过研究 \(F\) 的生成函数 \(G\),我们将看到:
直接暴力通分,显然是不行的。如果我们类似分治NTT,分治地通分,显然复杂度的瓶颈在于求分母:这就是分治NTT,所以复杂度还是 \(O(n\log^2 n)\) 的。
这样,我们就变成了求一个生成函数的 \(z^1\sim z^m\) 项系数。它形如:
此时求 \(t(z)\) 模 \(z^{m+1}\) 意义下的逆 \(t^{-1}(z)\),然后直接求 \(s(z)t^{-1}(z)\) 的对应项系数即可。
时间复杂度 \(O(n\log^2 n+m\log^2 m)\)。
不是很难,但对我很难。
首先容易考虑到:设 \(dp(i)\) 表示 \(i\rightarrow n\) 的期望步数。然后 \(dp(i)\) 会有一个对所有 \(a,b\) 都不同的转移。
这个转移的形式是取 \(\min\) 的,而且与 \(dp(0),dp(i),dp(i+1)\) 有关,所以这样直接下去是没有任何出路的。
这个题有意思的地方就在于通常无往而不利的倒着设计 dp 状态反而行不通,在出现诸如“清零”这样情况的时候直接正着做有奇效。
设 \(dp(i)\) 是 \(0\rightarrow i\) 的期望步数,对于一个 \(a,b\),设 \(\alpha = \frac{a}{A},\beta = \frac{b}{B}\),我们将看到:
然后常规地比较 \(\min\) 不取 \(dp(i)+1\) 的时候发生了什么,我们将看到这说明:
所以当我们按照 \(\frac{\alpha+\beta-\alpha\beta}{\alpha}\) 排序后,不取 \(dp(i-1)+1\) 的物品是一段前缀。
枚举前缀长度,对所有可能取 \(\min\) 即可。时间复杂度 \(O(kAB)\)。
我们理一下发现一个难点是想到正着做。因为有个清零,如果你倒着,\(dp(i)\) 肯定会出现 \(dp(0)\),但是这种情况如果是正着做只不过依旧是 \(dp(i)\) 罢了。还有一个点,是正着做的转移并不好推,这里实际上是从刷表的角度去推的,即从 \(i-1\) 去推到 \(i\)。我们注意到有一个 \(f(i)-f(i-1)\) 实际上是利用了期望线性性:\(0\rightarrow i\) 的期望等于 \(0\rightarrow i-1\) 的期望加上 \(i-1\rightarrow i\) 的期望。
考虑如果修改了 \(u\),则所有经过 \(u\) 的路径都将可以合法( \(a_u\) 取一个极大的 \(2^k\)),所以我们可以视作把 \(u\) 删掉,形成两颗独立的树。
设 \(f_u\) 为 \(u\) 到根的异或和,经典套路是 \(d(u,v)=f_u\oplus f_v\oplus a_{lca}\)。
显然从下往上地枚举 \(u\) 作为 \(lca\),若有以它为 \(lca\) 的路径不合法,则删除点 \(u\)。这个贪心成立,我们假设 \(u\) 子树内路径全部合法,在 \(u\) 处第一次出现不合法,则我们要么删除 \(u\),要么删除这条不合法路径上的其它任意一点。你发现删 \(u\) 是最优秀的,因为可以减少继续向上传递的点数最多。
所以我们要 check 是否有跨越 lca 的不合法路径,预处理 \(f\) 以后 dsu on tree 即可,太典了。
显然每个技能贡献一个区间,然后变成了选择若干区间覆盖 \([1,n]\) 的方案数。
这是个经典问题。首先我们按照 \(r\) 排序(\(r\) 相同按照 \(l\) 降序排序)。然后考虑设 \(dp(i)\) 代表 \([1,i]\) 被覆盖且 \(i+1\) 没有被覆盖的方案数。
当我们加入一个 \([l,r]\) 的时候,显然 \(dp(r)\) 会加上 \(\sum_{i=l-1}^{r}dp(i)\)。另外,对于 \(i\le l-2\),\(dp(i)\)都应该乘上 \(2\)(因为选它和不选对覆盖的极长前缀是不受影响的)。用线段树维护即可。复杂度 \(O(m\log n)\)。
没做出来多少有点菜了。
题目明示一定有解。所以,只要 \(N=2^n\) 且满足至少有 \(\frac{N}{2}\) 个人可以直接被击败,记作 \(S\),不能直接击败的人,必定可以被一个 \(S\) 中的人击败。
只要满足上面的条件,就一定有解。我们考虑构造地证明这件事,也就做完了题目。
\(n=1\) 的情况是平凡的。
考虑 \(n\ge 2\),设有 \(a\) 个人不能被直接击败,则 \(a\lt 2^{n-1}\),考虑把这些人两两匹配,则还会剩下 \(\left\lceil \frac{a}{2} \right\rceil\) 个这样的人,当 \(a=2^{n-1}-1\) 的时候这是不合法的,因为在下一轮 \(a=2^{n-2}\)。但是注意到我们并没有利用这 \(a\) 个人分别能被 \(S\) 中的一个人击败这条性质。同时我们也不能保证在下一轮里,这 \(a\) 个人存活下来的人,每个都能被存活下来的 \(S\) 中的某个人击败。
考虑这样一个贪心的匹配:
不断寻找 \((x,y)\),满足 \(x\in S\),\(y\notin S\),且 \(x\) 可以击败 \(y\),然后让他们匹配。直到寻找不到这样的 \((x,y)\) 为止。
然后我们再让不能被 \(1\) 直接击败的人自相残杀。
最后把剩下的人随意配对(注意优先配对 \(1\))。
这样,不能被击败的人(设为 \(B\)),有些会被直接干掉,而且至少会被干掉一个(这就保证了个数不会大于等于 \(2^{n-2}\));如果 \(B\) 的某个人 \(x\) 不被干掉,它就存活到了下一轮,根据上面的贪心过程,我们发现所有击败这个人的人,已经和其它的人打过并且胜出了,所以一定有一个存活下来的人 \(X\in S\),满足 \(X\) 可以打败 \(x\),这就满足了第二点。
通过这样归纳的构造,就证明了一定有解。时间复杂度 \(O(N\log N)\)。
比较基础的前置是 ABC209E,一年前让我很痛苦的题。
这类题首先我们可以对 dag 的情况设计一个显然正确的 dp:设 \(f(u,0)\) 是位于 \(u\),轮到先手移动的结果(如果陷入环就是 \(\infty\)),\(f(u,1)\) 是后手的状态。然后就有
现在考虑一般图的情况。把我们的目标从另一个角度考虑:不是“计算” \(f\),而是“构造”满足上述约束的 \(f\),同时我们注意到若 \(u\) 无出度,则我们确认了若干初始状态,然后再和上面的约束统一。
事实上这个想法让我想到了解线性齐次递推式的过程:比如解 \(f_n=3f_{n-1}+2f_{n-2}\),我们会先对 \(f_n\) 进行构造使得满足 \(f_n-3f_{n-1}-2f_{n-2}=0\) 成立,然后将初始项 \(f_1,f_2\) 代入,确定整个 \(f\) 的解。其实上面的 dp 也是类似的思想。
从“构造”的角度来观察可以解决很多说不出来的迷惑。
然后考虑调整:我们先把所有状态的值设为 \(\infty\)(对于一般的问题,这个初始值的设置需要一点智慧,但通常都是很特殊的值,例如 \(0,\infty,-\infty\) 等,我们只需要最后检验是否满足约束即可),这样满足我们的约束,但是并没有和初始值达到统一。然后,考虑从确定为 \(0\) 的终止状态反推,去调整不满足约束的状态。
比如如果 \(3\rightarrow 5\) 有边,且 \(5\) 无出度,那么 \(f(3,0)\) 一定不会是 \(\infty\) 了,这就是一个调整。
显然一个点只有被调整了,才会去对其他点产生新的约束。我们考虑把被调整过且未去对其他点进行影响的点按照值升序排序,每次取最小的更新(其实是一个dijkstra的过程)。
考虑 \(f(u,0)\) 只要被更改,就可以压入队列,而对于 \(f(u,1)\),只有它能到达的每个 \(v\),\(f(v,0)\) 的值都被修改了,它才会被修改,否则必定有一个 \(f(v,0)=\infty\),那么 \(f(u,1)\) 也就是 \(\infty\)。
通过这样一个“构造”过程的推导,就可以解释清一个类似反向拓扑+dijkstra做法的原理。
事实上这是一类比较有趣的题型,其思想看上去也很能有进一步应用,虽然我还没得到什么有趣的 idea,也许未来会被出成别的题也说不定。
这个题的约束看起来很多很恐怖,考虑建 trie。然后我们发现这是一颗 \(n+1\) 层满二叉树且我们会选择若干叶子(一个叶子可能被选多次),一个叶子被选了 \(k\) 次,就会把到根的路径上每个点加上 \(k\),设一个点 \(u\) 的值是 \(c_u\),则它的子树内选择的点的次数和 \(\le c_u\)。这就把问题转成了一个可做的形式。
但是子树点的次数和 \(\le c_u\) 是 \(\max=f\) 的必要条件而不是充分条件,因为你可能选出来 \(\gt f\) 个点。
考虑设 \(f(u,i)\) 是 \(u\) 子树最多只能选 \(i\) 个点的方案数,则我们有转移:
但考虑还有这样一种情况:左子树最多能选 \(5\) 个,右子树最多能选 \(3\) 个,而 \(c_u=7\),则它会贡献到 \(f_{u,7}\) 上,所以最终的 dp 方程是:
然后因为是满二叉树,本质不同的 \(dp\) 状态只有 \(n\) 个,所以做 \(n\) 次卷积即可。
设 \(N=2^n\),时间复杂度为 \(O(n^2\times N)=O(N\log^2 N)\)。
来自十年前的神题。
注意到如果填完了前 \(i\) 个字符,则右边界一定随着行的增加而递减。事实上把整个网格看成一个 \((0,0)\sim (n,m)\) 的坐标系,则左下角是 \((0,0)\),右上角是 \((n,m)\),右边界等价于从 \((0,0)\) 出发,每次向上或向右走一步,走到 \((n,m)\) 的一条路径。
所以路径只有 \(\dbinom{n+m}{n}<=2\times 10^5\) 种,我们记这个数目为 \(\omega\)。
对所有边界进行重新编号后我们考虑设 \(f(x,i)\) 代表前 \(x\) 种字符填完,形成的轮廓线编号为 \(i\) 的方案数,通过适当的对边界线排序,我们会发现有类似的一个形式:\(f(x,i)=\sum_{j\lt i}f(x-1,j)\),其中 \(j\) 完全要被 \(i\) 包含进去,同时你还得判断 \(i-j\) 这一段是否都能填字符 \(x\)。
但是这样我们发现很难做到低于 \(\omega^2\) 的复杂度,仍然不能通过。
考虑如果第 \(x\) 个字符出现了(如果没出现答案就是 \(f(x-1,i)\)),那么必定会首先在轮廓线的某个拐点出出现,所以我们可以枚举 \(O(m)\) 个拐点,在 \(2^m\) 的时间内枚举哪些拐点出现了字符 \(x\),然后去进行容斥(比如说有两个拐点 \(A,B\),那么就是 \(A\) 出现 + \(B\) 出现 - \(A,B\) 都出现)。这样你就可以单次 \(O(2^m)\) 的转移。
这里实现上要作注意,如果是第一层枚举 \(x\),第二层枚举 \(i\),然后枚举所有可能的 \(2^m\) 个状态,然后你还要 \(O(n+m)\) 处理出新的状态,最后可能还要带一个 map 查询的 \(log\),那么复杂度就变成了 \(O(26\times \omega\times 2^m\times (n+m)\times \log \omega)\),这显然是恐怖的。实践证明这个做法至多也只能通过 \(n,m\le 9\) 的做法(而且是在本题 15s 的恐怖时限下)。
但是考虑对所有相同的 \(i\),其实 \(2^m\) 个状态里有很多重复的东西。具体来说,我们可以先更改转移顺序:先枚举 \(i\),再枚举 \(x\),然后对于每次的 \(i\),把 \(2^m\) 个状态具体是什么预处理出来,并且把它们的限制处理出来(要么 \(x\) 取任何值都有效,要么 \(x\) 取某一个值有效,要么无效),同时把它们的编号先用 map 问出来然后存起来,这样不考虑内层转移,复杂度是 \(O(\omega\times 2^m\times (n+m)\times \log \omega)\),相当于你砍掉了一个 \(26\) 的常数;然后内层的复杂度是 \(O(\omega \times 26\times 2^m)\),相当于砍掉了 \((n+m)\log \omega\) 的系数。这样就可以通过本题。
似乎本题还可以进一步加速:把容斥的过程压进 dp 里,再开一维。但我并不是很会这个做法,如果有人会的话欢迎教教。
又是十年前的神题,不过比上面的简单很多。
首先根据期望线性性,我们转为对单个位置求期望。
设 \(x_{i,j}\) 是 \(i\) 号比赛是否会有一场在第 \(j\) 天举办,则我们将看到:
(这个技巧其实对任意次方都是成立的)
考虑一轮锦标赛,只会有最多一场在同一天举办。所以可以设 \(y_{i,j,k}\) 表示 \(i\) 号比赛的第 \(j\) 场是否会在第 \(k\) 天举办,则有:
把这个展开式放到最上面的式子,我们发现我们会对所有 \((a,b,c,d)\) 四元组去计算,四元组的意义是 \(a\) 锦标赛的第 \(b\) 场,和 \(c\) 锦标赛的第 \(d\) 场同时在第 \(j\) 天举办的期望。我们将发现剩下 \(m-2\) 个锦标赛的取值是无所谓的。又因为这里权值是 \(1\),所以期望就是概率。那么分母就是 \(n^2\)(如果 \(a=c\) 那么就是 \(n\),这种情形需要特殊考虑),而分子其实要么是 \(1\),要么是 \(0\)。
我们发现 \(n=10^9\),所以不可能对每个位置算一下再加起来,但你注意到所有位置的期望的分母都是 \(n^2\),所以我们只关注所有位置的分子的和。而你枚举 \((a,b,c,d)\) 后就可以简单计算出这个四元组对多少个位置的贡献是 \(1\)(对于 \(a=c\),我们把分子分母同时乘上 \(n\),那么也容易计算它对多少个位置的贡献是 \(n\))。这样就在 \(O((m\omega)^2)\) 的时间内解决了问题,其中 \(\omega=\max\{len_i\}\)。
对我而言难度适当质量还不错的好题。
首先每种颜色的过程是独立的,这启示我们分开来对每种颜色单独考虑:这就引出建虚树的想法。
然后注意到颜色相同的情况下,钥匙之间没有本质区别,宝箱之间没有本质区别,分别视作 \(+1\) 和 \(-1\),我们发现实质上类似一个括号匹配的过程。
注意到此时只有 \(5\) 个钥匙,暴力枚举一个钥匙 \(x\),再枚举宝箱 \(y\),他们两能匹配当且仅当它们路径中间的同颜色点是匹配的。
所以你可以从每个钥匙为根然后对虚树 dfs,然后就可以找到所有的 \(y\),容易发现总共的 \((x,y)\) 点对不超过 \(O(n)\) 级别。
然后变成了这样的一个问题:给出若干条路径 \(s\rightarrow t\)(有向),你需要把所有路径上包含 \(s\rightarrow t\) 的路径的权值 \(+1\),然后询问若干条路径的权值。
考虑一条路径能被起点和终点两个点描述,假设 \(s\) 与 \(t\) 不是祖先关系,我们会看到:只有起点位于 \(s\) 子树,终点位于 \(t\) 子树的路径,才会被 \(+1\)。放到二维的 dfs 序平面上,这对应了一个矩形。而对于 \(s\) 和 \(t\) 是祖先关系的情况,有类似的讨论。所以问题变成了若干个矩形加后若干个单点查询,扫描线即可处理。
值得注意的是这样的题尽量使用树剖求 lca,我使用倍增几乎是贴着时限过去的。
时间复杂度 \(O((n+m)\log n)\)。
还没有上面那个有趣的 trash 题。
不难想到建 kruskal 重构树然后变成子树查询。
注意到一种颜色只会出现 \(10\) 次,每种颜色是独立的,所以考虑修改一次,就对这个颜色的点建出虚树,然后 dfs 虚树,在点 \(u\) 到他父亲之前的这条链答案是固定的,所以变成链加单点求和,通过树上差分改为单点加子树求和即可。复杂度 \(O(q\log n)\),常数为 \(10\)。
赛后 hdoj 的机子实在太慢了,所以要很极限地卡常。
很有趣的思维题。
考虑到我们求的就是树高的期望,这提示我们很有可能我们并不是先对高度为 \(i\) 的合法的树去计数。
注意到树高就是 bfs 序分的层数 \(+1\),所以我们可以考虑把这个问题变成 bfs 序分的层数的期望,而根据期望线性性,它等于每个位置 \(i-(i+1)\) 之间分层的期望。
注意 \(k=0\) 的话是 \(\infty\),而题目没有特殊说明,所以暗示了题目的输入保证了至少存在一个合法的树。
只给出 \(dfs\) 序当然是没法确定唯一树的,只给出 \(bfs\) 序当然也不行,但是如果既给出了 \(dfs\) 序,又利用 \(bfs\) 序确定了每个点的 \(depth\),那么结论是只可能确定出一颗树(当然也可能矛盾,导致没有符合条件的树)。
考虑从根开始,然后下一个节点,我们知道了 \(dfs\) 序中当前节点和下一个节点的 \(depth\),那么就知道“下一个节点”在这颗树中应该是哪个点的儿子(所以有 \(depth_{d_{i+1}}\in [2,depth_{d_{i}}+1]\),另外我们发现按照这个顺序,另外,遍历是有顺序的,比如如果在 bfs 序中 \(5,3\) 同层且 \(5\) 先出现,则在 \(dfs\) 序中 \(5\) 也应该先出现。我们发现,第一个条件的合法让我们能确定树结构,第二个条件的合法让我们遍历节点的顺序不会有矛盾。
那么就分析的差不多了。我们为了方便起见,首先把 \(bfs\) 序转成 \(1\sim n\) 的形式,然后,如果 \(i\) 的位置,在 \(dfs\) 序中,晚于 \(i+1\) 出现,则 \(i-(i+1)\) 必须分段。在必须分段的点确定过后,设 \(dfs\) 序中第 \(i\) 个位置是 \(d_i\),如果 \(d_i<d_{i+1}\),那么 \([d_i d_{i+1})\) 中最多只能有一个分段点。这样,有一些点就一定不能分段。
一定分段的点,对期望的贡献一定是 \(1\);不能分段的点,对期望的贡献一定是 \(0\)。那么,剩下的未确定的呢?我们会发现一个问题:我们怎么处理形如:一个区间只能有至多一个点选 \(1\),其它点选 \(0\) 这样的约束呢。
这里要有一个整体的观念,就是说 \(dfs\) 序一定是一个 \(1\sim n\) 的排列。如果 \(d_i+1=d_{i+1}\),那么你只对 \(d_i\) 一个位置做约束,那么它选不选随意;如果 \(d_i+1\lt d_{i+1}\),那么所有大于 \(d_{i}\) 且小于 \(d_{i+1}\) 的数都会排布在 \(i-(i+1)\) 的两侧。我们会意识到,这就意味着 \([d_i, d_{i+1})\) 中一定存在至少一个点分段了,那么这个区间的其它点已经被确定只能不分段,就不存在问题了。
所以我们得出结论,此时没被约束的点确实是独立的,贡献为 \(0.5\)。
比上面那个思维简单很多,但是模拟的时候因为排序 fst 了......
设 \(f(u)\) 是当前位于 \(u\),答案位于 \(u\) 的某个子树,找到的期望步数。那么当答案不在 \(u\) 子树的时候怎么处理?我们发现此时一定会在若干次搜索后走回到 \(u\) 再走回去,所以设 \(g(u)\) 是答案不在 \(u\) 子树,走回去的步数(这里不是期望,因为你已经确定了答案不在 \(u\) 子树,但是主人公还不清楚这个事实)。
\(g\) 的转移是容易的:如果当前点有一个虫子,那么就是 \(g(u)=2\),否则 \(g(u)=2+\sum_{v}g(v)\)。
那么 \(f\) 呢?我们是对所有 \(u\) 的儿子的排列 \(v_1,v_2,...,v_k\),最小化这个式子:
\(cnt_u\) 是 \(u\) 子树内的儿子个数。
我们发现 \(f\) 相关的项是确定的,问题在于最小化 \(\sum prob\times presumg\)。
到这里就是简单的 exchange-argument 问题了,通过研究相邻两项的关系,我们会发现把儿子按照 \(\frac{g}{cnt}\) 来排序是最优秀的。
时间复杂度 \(O(n\log n)\)。
这个题模拟没搞出来有点降智了。
容易往一个方向去想:一次行动会把一个区间的垃圾带回来,但是其实是错误的。如果上来就直接利用这个结论然后去斜率优化就彻底误入歧途了。
但是一个策略是确定的:假设我们一次行动,把带回来的垃圾按照坐标排序,记为 \(x_1,x_2,...,x_m\)。那么我们的移动策略是什么?一定是先移动到 \(x_m\),然后往回走,路途中再带上要收集的垃圾。
我们来推一下答案:不妨把 \(x\) 倒转,那么答案就是 \(x_{1}+\sum_{i=1}^{m}(i+1)^2(x_i-x_{i+1})\),我们定义 \(x_{m+1}=0\)。
化简以后得到 \(5x_1+\sum_{i=2}^{m}(2i+3)x_i\)。
我们把系数列出来会发现就是 \(5,5,7,9,11,13,15,...,\)。
如果放下垃圾没有代价,我们会发现一次搬一个垃圾是最优秀的。
如果放下垃圾有代价 \(X\) 呢?自然想到枚举这个次数,然后我们就只用让上面的贡献最小。距离原点越远,它对应的系数就会越小。我们假设用了 \(k\) 次,那么把系数列出来以后就很容易想到最优秀的构造方式:最远的 \(k\) 个给第一个 \(5\),次远的 \(k\) 个给第二个 \(5\),接下来的 \(k\) 个给 \(7\),然后给 \(9\),......,依次类推。不难发现预处理 \(x\) 的前缀和以后可以做到 \(O(n\ln n)\)。
感觉这种题对我来说能不能做出来完全随缘了......
有一个想法是我们把掉头这个事情忽略掉,因为宏观上来看就是直接穿过去了。这样我们确实可以找到所有蚂蚁结束的位置,但是我们并不能建立起一一对应。
自然地会给蚂蚁分配一个编号,当它们碰撞的时候,蚂蚁继续往前走,交换编号。
我们容易知道每只蚂蚁最后的位置,所以我们只需要求出它们各自的编号即可。
如果我们重新把蚂蚁按照输入顺序编号为 \(0\sim n-1\) 的话,我们考虑所有碰撞中,所有最早发生的碰撞:它一定是编号相邻的两个蚂蚁。
然后会发生什么?顺时针的那只,编号将 \(+1\)(模 \(n\) 意义下),逆时针的那只,编号将 \(-1\)。
然后把最早的碰撞考虑过后,我们来看目前的局面。此时再去研究次早发生的所有碰撞:我们发现通过归纳可以得出,当两只蚂蚁碰撞的时候,顺时针的那一只编号 \(+1\),逆时针的那只编号 \(-1\)。
讲个笑话,我模拟的时候手玩了半天都没发现这个编号更改的规律。
那么有了这个规律以后我们就只关注蚂蚁碰撞的次数了。不妨假设我们当前枚举的是一只顺时针的蚂蚁,那么考虑所有逆时针的蚂蚁。每 \(L\) 秒它显然会和每只逆时针的蚂蚁撞 \(2\) 次。所以我们令 \(t=T\bmod L\),然后找到多少只蚂蚁会和我们枚举的碰撞一次,多少只会碰撞两次即可,可以通过二分来找到。
逆时针也是同理的。然后我们就知道了每只蚂蚁的终止位置和终止时刻的编号,然后这个问题就做完了。
但是我的实现确实很丑,这是值得思考的。
仙人掌基础练习题。
首先我们知道路径的权值 \(\gcd\) 为 \(k\) 可以通过莫比乌斯反演来变成:路径权值为 \(k\) 的倍数的路径条数。
但是一般图的简单路径条数显然是个不可做问题...... 光是考虑两点之间的路径条数就很困难了。
所以这个图一定存在某些性质。题目里告诉我们:不存在边权和为偶数的简单环。
那么首先肯定不是树了。直觉比较好的话,很快会猜出来是仙人掌。感谢 zimpha 在这里给了一个简明易懂的证明:
考虑一个边权和为奇数的简单环。如果它有一条弦,那么分成的左右两个弧必定奇偶性不相同,这两个弧一定能取出一个,和这条弦组成一个小的简单环,满足边权和为偶数。
因此任何一个简单环内部不能存在弦。这就自然地引导出图是一个仙人掌。
然后问题变成了仙人掌上的简单路径计数。不难发现,建圆方树过后,两点 \((u,v)\)(圆点)之间简单路径个数是 \(2^{cnt}\),其中 \(cnt\) 是 \(u-v\) 路径上的方点个数。
因此对仙人掌做简单树上 dp 即可。
时间复杂度不是很会算........ 看上去是调和级数但你考虑一个权值的边不会只出现一条,所以感觉是 \(m\times \omega\) 的,其中 \(\omega\) 是 \(\max_{i=1}^{L}d(i)\),\(d(i)\) 是因子个数。肯定是比 \(m\ln m\) 慢不少的。
但我本地不加任何改动也就 2s 啊,hdu 的机子真的是慢出一定境界了。

浙公网安备 33010602011771号