不知名题单刷题记录
CF1172B
先钦定一个位置当作 \(1\)(根),显然有 \(n\) 种方案,那么每棵子树内的点都需要在环上是连续的一段。
于是有一个 dp,设 \(f_u\) 表示以 \(u\) 为根的子树的方案数,那么 \(f_u=\displaystyle\prod_{v\in son(u)}f_v\times(deg_u-[u=1])!\)。这个式子相当于是在安排每个子树和 \(u\) 的顺序。
观察这个式子,发现 dp 是没有必要的!答案直接就是 \(n\times\displaystyle\prod_{i=1}^{n}(deg_i)!\)。
CF109C
首先肯定是对于每一个 \(i\) 算有多少对 \((j,k)\)。
然后选的 \(j,k\) 发现可以分为在子树内还是外,于是有一个 dp,\(f_u\) 表示 \(u\) 子树内能选出多少合法点,\(g_u\) 表示 \(u\) 子树外能选出多少合法点。
唯一不显然的转移是,\(g\) 遇到不合法边的时候 \(g_v=g_u+f_u-f_v\)。
答案统计仍然是显然的。
CF1902D
首先 \([1,l-1]\) 和 \([r,n]\) 没有受到影响。
然后若修改后的路径经过 \((x,y)\),则原路径经过 \((sx_r+sx_{l-1}-x,sy_r+sy_{l-1}-y)\),这两个数组是前缀和数组(这一段指的是区间 \([l,r-1]\) 内)。
判断一个区间内有没有出现过一个点是简单的,把点哈希一下然后扔到 set 里二分出现位置 \(\ge pos\) 的第一个即可。
CF1000D
设 \(f_{i,j}\) 表示前 \(i\) 个数,上一段还剩 \(j\) 个接完的方案数。
答案显然就是 \(f_{n,0}\)。
转移显然,\(f_{i,j}=f_{i-1,j+1}+f_{i-1,j}\)。当 \(i\) 可以新开一段时,还有转移 \(f_{i,a_i}=f_{i-1,0}+1\),这个加上 \(1\) 的原因是多了一个从 \(i\) 开头的选择。
CF1512G
\(O(n\log n)\) 做法是显然的,且可以卡过去,这里不再讲。
我们考虑在线性筛的时候 dp。设 \(f_i\) 表示 \(i\) 的约数之和。有 \(f_{i\times prime_j}=f_i\times (prime_j+1)\)。
但是当 \(i\) 是 \(prime_j\) 的倍数时,会算重,需要减掉 \(f_{\frac{i}{prime_j}}\times prime_j\)。
于是就可以在线性时间复杂度内求出 \(f\) 了。
CF997B
打表找规律题。
写一个搜子,然后发现当 \(n>11\) 时答案是等差数列,然后就没了。
核桃 P10472 步步高升
首先我们假设 \(p_a\ge p_b\),显然有 \(\forall d\in (a,b),p_d<\min(p_a,p_b)\),否则显然可以用 \(d\) 换掉其中一个数。
当 \(p_a\le p_b\) 时,显然我们可以用单调栈对于一个 \(b\) 求出所有合法的 \(a\)。否则我们把序列倒过来做即可。
然后现在的 \((a,b)\) 只有 \(O(n)\) 对,每一对的 \(c\) 都是一个可空后缀。
我们把询问离线下来然后按 \(l\) 倒着扫,每次加入一些对,用线段树维护对的贡献。询问的时候直接区间查询即可。
洛谷 P4137
离线下来,然后询问按右端点排序,维护每个数最后一次出现的位置然后线段树二分找第一个没有出现的数即可。
洛谷 P3899
首先 \(b\) 在 \(a\) 上面是奶龙题。
然后发现选择 \(b\) 后,\(c\) 有 \(siz_b-1\) 中方案。显然 \(b\) 的 dep 和 dfn 都要在一个区间里,相当于查一个矩形内的点权和。
直接离线下来树状数组搞即可。
CF840D
非常牛的题。设最小合法出现次数是 \(t\)。考虑把区间内的所有数排序,每隔 \(t\) 个拉出来一个,显然如果有答案,答案必然会被拉出来。
然后我们只需要判断一下拉出来的数的出现次数是否合法即可。显然可以用主席树实现。
洛谷 P4577
\(f_{u,i}\) 表示 \(u\) 子树内选择的所有数都 \(\ge i\) 的答案,转移显然。暴力转移可以做到 \(O(n^2)\)。
\(\forall i\),显然 \(f_{u,i}\ge f_{u,i+1}\)。
直接用线段树合并维护整体 dp 会有区间修改,考虑差分一下,令 \(g_{u,i}=f_{u,i}-f_{u,i+1}\)。
合并完之后,我们要把 \(f\) 的一个后缀赋值成一个数。事实上,这种数的值都是一样的。于是差分数组只需要改两头,就变成单点修改了。
洛谷 P2824
二分答案,然后把序列搞成只有 \(0/1\)。
变成区间求一个数个数,区间赋值,求一个位置的值,线段树维护即可。
CF1372E
注意到把 \(1\) 堆到一列比分散开优。
所以我们钦定一个顺序,使得我们按顺序放时,所有能放到这一列的 \(1\) 都放进去。
于是区间 dp,\(f_{l,r}\) 表示 \([l,r]\) 的答案,枚举一下区间内钦定的第一个点,然后再判一下有几个 \(1\) 能放进去。时间复杂度是 \(O(n^4)\) 量级的。
abc422g
云浅学长推的题。
第一问是搞笑完全背包。
第二问考虑实际上是在求什么,就是选出 \(x,y,z\) 分别是 \(A,B,C\) 的倍数。然后求 \(\sum\dfrac{n!}{x!\times y!\times z!}\),这个实际上是三个组合数相乘。
然后这个东西显然可以枚举 \(x,y\) 算,复杂度是 \(O(\dfrac{n^2}{AB})\) 的。
考虑 \(AB\) 比较小的时候怎么办,既然我们有除掉 \(AB\) 的做法,就可以考虑去想一个乘 \(AB\) 的做法。
跟 \(AB\) 有关的东西有余数,于是我们考虑一个 dp,\(f_{i,j,k}\) 表示当前放了前 \(i\) 个球,第一个盒子里放的数量模 \(A\) 是 \(j\),第二个盒子里放的数量模 \(B\) 是 \(k\) 的方案数(只往前两个盒子里放球)。
答案就是 \(\sum f_{n-k\times C,0,0}\times \binom{n}{k\times C}\)。
复杂度是 \(O(n\sqrt(n))\) 的。
洛谷 P10144
对 \(h_i<h_{i+1},h_i>h_{i+1},h_i+h_{i+1}<2L,h_i+h_{i+1}>2L\) 分讨,然后可以得出在这四种情况下分别一定可以怎么跳。
然后把每个东西都反过来,例如 \(h_i<h_{i+1}\rightarrow h_i\ge h_{i+1}\)。现在就是在这四种情况下一定不可以怎么跳。
考虑矛盾都会怎么出现。
我们现在记四种情况分别是一开始的四种情况每个都反过来的情况。
第一种是四个情况全都成立。
第二种是 \(h_{i-1}\le a_i,h_{i-1}+h_i\le 2L,h_i\ge h_{i+1},h_i+h_{i+1}\le 2L\)。
第三种是第二种反过来(等于仍然要取到)。
发现这两个限制一个是限制 \(L\) 的下界,另一个是上界。但是我们发现,第一种情况会扣掉一个数不能选。可能会出现一些问题?
其实并不会,因为第一种情况成立的时候,后两种情况会直接交出来一个空区间。
显然对于一个给定的 \(u\),\(v\) 是一段连续的前缀,所以我们可以二分最远的 \(v\)。check 只需要做两个 RMQ 比大小,直接上 ST 表即可。
洛谷 P8173
首先只有图是一棵树 Bob 才能赢,否则 Alice 可以在环山随机游走。
链是简单的,从一头扫到另一头再扫回来即可。然后我们考虑链上挂了点东西怎么办。
不妨先考虑只有一个点上挂了东西。发现挂深度为 \(1\) 的链没有影响。如果挂深度为 \(2\) 的链,发现 Alice 可以在这反复横跳,需要管一下。
其实管的方式很简单,就是扫到这个点的时候往下走一下再回来。
然后如果挂了深度为 \(3\) 的东西,可以发现 Bob 赢不了。
所以直接把直径找出来,对于每个深度为 \(2\) 的坑下去一次再回来即可。
CF2146E
假设我们现在的 \(i\) 是确定的。然后不难发现对于一个确定的 \(\operatorname{x}\),你的左端点一定在他最后一次出现左边。
然后考虑加一个数,其实就是把 \(\operatorname{mex}\in[0,a_i-1]\) 的贡献全部 \(+1\),\(\operatorname{x}=a_i\) 这个位置改成 \(0\),其他不变。这个直接上线段树维护即可。