Codeforces/TopCoder/ProjectEuler/CodeChef 散题笔记 (持续更新)

时间:2023-03-09 02:19:29
Codeforces/TopCoder/ProjectEuler/CodeChef 散题笔记 (持续更新)

  最近做到了一些有趣的散题,于是开个Blog记录一下吧…

  (如果有人想做这些题的话还是不要看题解吧…)

2017-03-16


  PE 202 Laserbeam

  Codeforces/TopCoder/ProjectEuler/CodeChef 散题笔记 (持续更新)

  题意:有一个正三角形的镜子屋,光线从$C$点射入,求恰好反射$12017639147$次后在$C$点射出的方案数。

  题解:关于反射问题容易想到对称性,不断对称翻转正三角形,可以密铺整个平面,这样一条反射$k$次的路径对应平面上经过$k$条边的路径。

  然后取$CB,CA$为基,把平面画正,就能得到一个带有平行的对角线的网格图,稍微观察一下就能发现反射$2k+1$次就意味着目标点的$x+y=k$。

  然后算上射出点必须在$C$点的限制,有$x \equiv y \pmod{3}$,并且为了不在之前从其他点射出,需要满足$(x+1,y+1)=1$。

  于是变成一个计数题,因为$x+y$是固定的,所以求GCD时利用GCD的性质可以变成单独的$x+1$与常数互质的计数,暴力或者容斥都可以…

  做的时候虽然不费什么力气就完成了第一步的转化,但是统计答案时我首先想的是暴力…感觉比较糟糕呀…为什么我老是那么暴力…

  PE 208 Robot Walks

  Codeforces/TopCoder/ProjectEuler/CodeChef 散题笔记 (持续更新)

  题意:有一个机器人,每步行动只能选择顺着当前方向顺时针或者逆时针转弯移动五分之一圆,求行动$70$步后恰好回到原点的方案数。

  题解:一开始就有种很不好下手的感觉…因为直接考虑统计操作序列就难以表示回到原点的限制…而直接对着位置进行统计的话又会因为只能转弯的限制而变得不好统计…于是我开始考虑路径的嵌套,一开始的想法是先构造出绕若干圈的方案,然后再在中间插入延长路径的步骤…想想画画,很久之后突然发现是自己想多了…一开始就直接考虑各方向伸展的长度就好了,转弯的限制很容易就能转化为另一个问题…然后就轻易地变成每方向走$14$步,并且相邻两步的方向相差$1$的方案数。其实就是一个五个点的环且环上的边都是$14$重边的图的欧拉回路计数…没怎么想就直接暴力弄了个$5 \times 14^5$的DP算了…就这么暴力地解决了。

  感觉这道题性质非常特殊呀…这种暴力地做法似乎浪费了那么好的性质,感觉不优美…不过我暂时没想到其它办法,以后多了解一点欧拉回路计数之后可能就会有更好的想法了。

  PE 268 Counting numbers with at least four distinct prime factors less than 100

  题意:和题目名字一样,就是算一下$10^{16}$以内有多少数有至少$4$个$100$以内的质因数。

  题解:一眼就能看出来是最简单的容斥原理…没什么好说的…不过我花了出奇长的时间…大概是对容斥的理解还不够深刻吧,最基本的$\pm 1$的容斥形式只是照着感觉和经验写的,而其中的道理却没有理解透,所以才会花那么久…明明容斥已经不知道用过多少次了,却还没弄清楚,真是得反思呀…其实只要知道当前状态被计数次数和它应该被计数次数的差就能得到容斥系数了,预先跑一次求出每种质因子个数的容斥系数就能算了。(最基本的容斥形式因为是从$1$开始的,所以得到的就会是$\pm 1$交替的系数,这里则是从$4$开始,所以会得到不一样的系数)

  


  [2017-03-29] UPD:  今天做到一道题解写错的容斥概率题,促使我进一步地探究这种子集形式的容斥的更加简单的形式。

  我做PE268时的原始式子,其中 $a_n$ 代表大小为 $n$ 的集合的容斥系数:

  $$ a_k = 1 - \sum_{i=0}^{k-1} \binom{k}{i} a_i $$

  考虑应用二项式系数的递推式拆成两项(本意是想得到递推式,但是并不成功),化简后可以得到一个更加干净的形式:

  $$ a_k = -\sum_{i=0}^{k-1} \binom{k-1}{i-1} a_i $$

  (原本得到的$i$的下界是$1$,因为有个为零的二项式系数在,所以加上$0$处的值不会影响,并且式子更加简单)

  现在假设 $a_0,a_1,\cdots,a_{m-1} = 0, a_m = 1$ (稍微一般一点的形式就是这种,容斥求大小不小于$m$的子集)。

  我手算了前几项,发现 $ a_k = (-1)^{k-m} \binom{k-1}{m-1} $,于是我应用归纳法证明这个东西…

  首先显然对$0,1,\cdots,m$成立,假设对不超过$k-1$的自然数成立,则:

  $$ \begin{aligned} a_k & =  -\sum_{i=0}^{k-1} \binom{k-1}{i-1} \binom{i-1}{m-1} (-1)^{i-m} \\ & =  -\sum_{i=0}^{k-1} \binom{k-1}{m-1} \binom{k-m}{i-m} (-1)^{i-m} \\ & =  - \binom{k-1}{m-1} \sum_{i=0}^{k-1} \binom{k-m}{i-m} (-1)^{i-m} \\ & =  - \binom{k-1}{m-1} \sum_{i=0}^{k-1} \binom{i-k-1}{i-m} \\ & = - \binom{k-1}{m-1} \binom{-1}{k-1-m} \\ & = - \binom{k-1}{m-1} (-1)^{k-1-m} \\ & = (-1)^{k-m} \binom{k-1}{m-1} \end{aligned} $$

  于是就得到了稍微更加一般的容斥系数的简单形式啦~

2017-03-20


PE 252 Convex Holes

Codeforces/TopCoder/ProjectEuler/CodeChef 散题笔记 (持续更新)

  题意:给定一个大小为$500$的点集,求一个面积最大的凸区域满足顶点在给定的点集中,且区域内部没有点。

  题解:一开始想枚举起点然后用单调队列瞎弄…结果没有过$20$个点的样例…于是考虑DP,枚举凸多边形的左下点,忽略左侧的点,对右侧的点极角排序,用状态$f_{i,j}$表示当前决策的凸多边形的最后一条边是$j \to i$时的最大面积,转移时用叉积判断就可以保证DP出一个凸多边形。至于内部没有点的条件,可以预处理$c_{i,j}$表示$i \to j$这条边能不能取,判断的方法就是判断$[i+1,j-1]$区间内的点是否都在边$i \to j$左侧。于是整道题就$O(n^4)$地解决了(因为数据随机所以合法的转移比较少,10秒就能出结果)。

2017-03-21


PE 289 Eulerian Cycles

Codeforces/TopCoder/ProjectEuler/CodeChef 散题笔记 (持续更新)

  题意:给定一个由圆整齐排列成的图,求$6 \times 5$个圆组成的图中的不相交欧拉回路个数。

  题解:看到这种形式和范围就想插头DP…于是直接写插头DP…没什么思考难度(雾)…各种细节各种处理比较恶心…写了快一天…(怪不得通过人数比较少)

2017-03-25


  PE 255 Rounded Square Roots

  题意:

  给出一种有趣的求整数平方根四舍五入结果的迭代法,求对于所有$10^{13} \leq n < 10^{14}$的迭代次数的平均值。

  令$d=n的位数$,初始化 $x_0=2 \times 10^{\frac{d-1}{2}}$($d$为奇数),$x_0=7 \times 10^{\frac{d-2}{2}}$($d$为偶数)

  重复下列步骤,直到$x_{k+1}=x_k$

  $$ x_{k+1} = \left \lfloor \frac{ x_k+ \left \lceil \frac{n}{x_k} \right \rceil }{2} \right \rfloor $$

  题解:

  关于这个迭代法…想了一下,如果去掉去整就是牛顿迭代…至于为什么加上取整可以得到四舍五入的结果…我并不知道…

  观察到这个式子的形式,在每一步都有一大段数产生同一个$x_{k+1}$,于是直接递归计算所有区间。如果分析复杂度上界的话递归式大致是$T(n)=\sqrt{n}T(\sqrt{n})+O(\sqrt{n})$,复杂度相当高…但是基于牛顿迭代法的收敛速度,这个递归式其实只会展开前面几层…跑了一下实际递归次数只有一亿多次,跑几秒就出来了…

2017-05-11


  (好久没有更新啦…

  PE 270 Cutting Squares

  Codeforces/TopCoder/ProjectEuler/CodeChef 散题笔记 (持续更新)

  题意:

  给定一个正方形,每条边上有 $n+1$ 个点,求 $n=30$ 时三角剖分的方案数。

  题解:

  如果这个是一个凸多边形的话,显然就是卡特兰数了。现在只是加多了一条规则,不能连接同一条边上的两个点。于是按照原来推出卡特兰数点方法来,按某种顺序把边定序,枚举第一条边把多边形剖成两块来递归。这题如果把点编号,以一条边点两端编号形成的有序对为关键字定序,那么接下来需要加入边的点对应原图形上的一个区间,所以以 $f_{i,j}$ 表示状态即可DP。复杂度 $O(n^3)$ 。

2017-05-13


  PE 272 Modular Cubes 2

  题意:

  求满足 $ x^3 \equiv 1 \pmod{n} $ 恰有 $243$ 个解,且 $n \leq 10^{11}$ 的 $n$ 的和。

  题解:

  首先我们考虑这个方程有多少解。可以很容易地证明,对于大于$3$的质数模数,这条方程只有$1$个或$3$个解(拉格朗日定理给出了$n$次同余方程解数的上限$n$)。另外,通过拉格朗日定理可以推出一个有用的结论,即 模素数同余方程 $f(x) = \sum_{i=0}^n a_ix^i \equiv 0 \pmod{n}, \ (n < p, p \not | a_n) $ 存在$n$个解的充要条件是 模$p$意义下多项式 $f(x)$ 整除 $x^p-x$。

  而恰好这题中的 $f(x)$ 就是 $x^3-1$,这种形式的因式分解具有很好的性质,由竖式除法过程我们可以得到存在满足条件的因式分解的充要条件 $3|p-1$,同时我们得到这一类型因式分解的结果:$x^a-1 = (x^b-1)(x^{a-b}+x^{a-2b}+\cdots+x^{b}+x^0), (b|a)$。

  回到这题,我们还要解决下一个问题,现在我们只能通过CRT得到那些Square-Free的数的结果,剩下的还需要推导。考虑从 $f(x) \equiv 0 \pmod{p^c}$ 推到 $f(x) \equiv 0 \pmod{p^{c+1}}$,对于第二个方程的任何一个解,一定满足是第一个方程的解,于是他们可以写成 $f(x_0+kp^c) \equiv 0 \pmod{p^{c+1}} $,其中$x_0$是第一个方程的一个解。我们把这条式子展开,式子里的$kp^c$项在告诉我们可以放心地把多项式展开,因为对于$c \geq 1$一定满足 $(kp^c)^2 \equiv 0 \pmod{p^{c+1}}$ 。于是我们按二项式定理展开多项式的每一项,因为前面的性质,每项只会展开出两项,于是我们得到 $f(x_0)+kp^cf'(x_0) \equiv 0 \pmod{p^{c+1}}$ 。其中$f'(x)$就是$f(x)$的导数(算一下上面的过程就知道这是怎么来的了)。然后注意到两侧每一项都能被$p^c$整除,于是我们除以$p^c$,得到 $\frac{f(x_0)}{p^c}+kf'(x_0) \equiv 0 \pmod{p}$,整理得到 $kf'(x_0) \equiv -\frac{f(x_0)}{p^c} \pmod{p}$。很好,变成了熟悉的一元一次同余方程,那么我们直接可以知道,这条方程有唯一解的充要条件就是 $f'(x_0) \not \equiv 0 \pmod{p}$。现在我们看看题目中怎么样,$x^3-1$的导数是$3x^2$,因为模是素数,且原方程没有零解,于是除了模$3$的特殊情况外,模$p^c$的解数等于模$p^{c+1}$的解数。所以对于所有整数我们都可以计算了。

  于是这题就变成了,求恰好含有$5$个模$3$余$1$的质因子的数的和。但是还不对,因为$3$的情况是需要特殊讨论的,模$3$是不合法的,但是模$3^k, (k>1)$是合法的,所以需要特殊判断。至于这个东西怎么求…可以玄学一下,考虑从小到大枚举$5$个质因数的幂,最后再枚举一个其它质因子的幂的积。前一部分的枚举因为比较稀疏,总共次数只有千万级,而后一部分的枚举可以通过预处理$O(1)$算。因为它最大为$\frac{10^{11}}{7 \times 9 \times 13 \times 19 \times 31}$,非常小,线性预处理即可。

2017-06-12


  PE 365 A Huge Binomial Coefficient

  题意:

  求 $ \sum_{1000<p<q<r<5000} \binom{10^{18}}{10^9} \mod (p \times q \times r) $ 。

  题解:

  我真是失了智了。前几天遇到一道组合计数,推出了简单的形式,却因为是long long级别的二项式系数模一个 $ 10^9 $ 而弃疗了…

  因为映像中这种东西非常不好做呀…(其实是记错了 这个级别的质数模数才不好做 大概可以多项式多点求值做)

  然后这几天非常烦躁于是来看看PE,随机点了一道这个简单题…然后我就来推了…

  现在要算二项式系数其实就是算阶乘,对于比较小的质数模数$p$,可以直接按模$p$分段,完整的段根据威尔逊定理就能算,然后暴力计算最后不完整的一段,同时把$p$的倍数提出来单独计算,因为它们没有逆元所以要等到最后再计数。然后这些$p$的倍数除掉$p$之后刚好又是一个规模变小的子问题,分下去计算就好…如果我们预处理好阶乘和逆元的话,整个过程就是$log(n)$的了。

  一顿失了智的操作后过了这道题…然后突然发现这就是Lucas定理呀…简直老年痴呆…不过好处是如果直接用Lucas定理的话只能计算质数模数,这个可以算质数的次幂的模数,姑且算个非常显然的推广吧…

2017-06-12


TC SRM 691 div1 Medium   MoneyManager

  题意:

  有 $n$ 个任务,每个任务会提供一个经验值 $a_i$ 和一个收益系数 $b_i$,初始时经验 $E=0$,当完成一项工作时,将会先获得对应经验,然后获得 $E \times b_i$ 的报酬。

  另外,在完成恰好 $\frac{n}{2}$ 个任务后,将会额外获得 $X$ 的经验。现在要规定一个完成任务的顺序,使得总收益最大,输出最大收益。

  数据范围:$ n \leq 50, a_i,X \leq 10^5, b_i \leq 10 $

  题解:

  (终于放上来一道不是PE的题…)

  首先不考虑完成一半任务的额外经验,看一下什么时候有最大收益。收益的式子看起来很迷,不是很好看出性质,但是如果结合图像,就能发现从原点开始把宽$a_i$高$b_i$的矩形右上角对左下角接起来围成的左上部分的面积就是收益。考虑这整一大块范围,长宽都是一定的,于是我们发现只要这个图形尽量往外凸就好了,所以最优方案就是一个 $\frac{b_i}{a_i}$ 递增的凸壳。

  然后考虑加入额外经验,这时任务被划分成前一半和后一半,注意到这个划分如果确定下来,两边仍然分别遵守上面的结论。所以按照斜率排序后从大到小取来进行DP。

  注意到$b$非常小,所以令 $f[i][j][k]$ 表示决策了$i$个,其中$j$个在前一半,并且这$j$个任务的$b$的和为$k$。那么前一半的贡献可以直接DP出来,但是后一半有些不方便,而且因为$a$范围很大,所以不能记在状态中,那么后半的贡献并不能留到最后算。所以为了解决这个问题,可以在最外层加多一层循环,枚举最终后一半的$b$的和,那么在DP过程中在前一半加入任务时也能计算出对后一半的贡献了。

  所以就有了 $O \left( n^2\left (\sum b \right )^2 \right )$ 的做法。看起来比较大,但是过程中常数小(比如DP的状态不满),是能够通过这道题的。

2017-06-15


CC SNCKPA16 MAKELIS

  题意:

  给定一个整数 $K \leq 10^5$,要求构造一个排列使得最长上升子序列个数恰好为 $K$ ,且序列长度不超过$100$。

  题解:

  有趣的乱搞题…显然可以通过构造让当前LIS个数乘以某个数,那么当然就想快速幂…但是需要增加一个的部分必须从底部再新建一整条而不能直接用上一层最靠下的数,所以序列长度是 $O(\log^2 K)$ 的。

  但是可以换一个方法,注意到在右侧的数不会影响在左侧的数,所以可以在左边先造一个大的 $2^k$ 种方案的序列,再在右边新加一串同样长度的序列来负责统计,右边的每个点比所在层左侧的所有点高。现在所有路径都是一样长的,所以如果在某层右侧新点的左边再加一个点,那么左侧产生的 $2^i$ 条路径就会算进答案。同时为了用来统计答案的点之间不要相互影响,那些代表取这一层的 $2^i$ 条路径的点需要从高到低排,而且在那串代表所有层的点的左边。于是右侧大致是一个V的形状。这样就能在 $O(\log K)$ 的长度解决问题了。

2017-06-18


CF 241D Numbers

  题意:

  给定一个长度为 $n$ 的排列和一个质数 $p$,求一个子序列满足:

  1、子序列非空

  2、子序列中所有元素的异或和为 $0$

  3、子序列中所有元素依次相接形成的大整数能被 $p$ 整除

  数据范围:$1 \leq n,p \leq 50000$

  题解:

  奇妙的乱搞题…如果数据范围只有几百的话,显然直接DP就好了。

  实际上,对于满足 $\gcd(p,10)=1$ 的 $p$ ,相接形成的大整数模$p$的变化是足够剧烈和混乱的,所以可以近似地看作随机。

  而对于特殊的质数 $2,5$,只要考虑最后一个数的个位是否能被整除。但是直接DP的 $O(n^2 \times 5)$ 的复杂度仍然很高。实际上这个整除的要求很松,在一个小范围内就能够找到解。

  所以可以设定一个阈值 $L=2^k$,然后忽略所有不小于 $L$ 的元素,于是复杂度会变成 $O(L^2p)$。

  至于正确性,可以估算一下,总共的子集数为 $2^L$,而异或结果只有 $L$ 个,而考虑异或的性质,每一位拆开,就会发现这些结果是均匀分布的。于是异或和为 $0$ 的集合有 $\frac{2^L}{L}$ 个。

  于是算上 $p$ 的条件,为了有比较高的正确性,至少要取二十几个数,所以最小的 $L$ 取 $32$。即可通过此题。

2017-06-19


TC SRM 560 div1 Hard  BoundedOptimization

  题意:

  给定一个表达式,形如 $ W = \sum x_ix_j $,其中 $i \neq j$,且无序对 $(i,j)$ 不会出现超过一次。

  另外给出 $n$ 个变量 $x_1,x_2,\cdots,x_n$ 的上下界,要求 $\forall i, L_i \leq x_i \leq R_i$。(注意$x_i$可以为实数)

  再给出一个额外的限制 $S$,要求 $\sum_{i=1}^n x_i \leq S$。求满足限制的 $W$ 的最大值。

  数据范围:$n \leq 13, 0 \leq L_i,R_i \leq 100, S \leq 1300$,时限两秒

  题解:

  $x_ix_j$ 这种形式应该叫双线性还是什么?不管了…

  首先因为变量非负,所以肯定是越大越好。  

  对于不含 $x_ix_j$ 项的 $i,j$ ,在和一定的情况下贡献显然是关于其中一个变量的一次函数,所以最优情况下会调整到至少一个碰到上界或者下界。

  所以可以 $n^3$ 枚举它们碰到上界还是下界或者是在中间。注意到任意两个在中间的变量 $i,j$,表达式中一定要有 $x_ix_j$项,否则不可能最优。

  这就意味这,对于满足这样的条件的 $x_i,x_j$,那些满足 $k \neq i,j$ 且枚举状态为在中间的 $x_k$ 的贡献和最优化无关,因为它们一定同时与 $x_i,x_j$ 产生了一样的贡献。

  所以,不确定的因素被排除了,现在当和一定时,贡献是关于其中一个变量的二次函数,于是就能知道最优情况下这两个变量的相对关系($x_i = x_j+c_{ij}$,其中 $c_{i,j}$ 是一个常数)

  那么根据总和,就能解出每个变量了。复杂度 $O(n3^n+n^23^n)$ ,其中大的那个是计算答案。

TC SRM 562 div1 Easy  PastePaintingDivOne

  题意:

  给一个最大 $50 \times 50$ 的印章,上面有些格子有红绿蓝三种颜色,不断地在一张无限大的白纸上按,有颜色的部分会覆盖纸上当前的颜色,按完之后把印章往右下移动一格重复。

  问重复 $T$ (至多$10^9$) 次后三种颜色的格子分别多少个。

  题解:

  题目很简单,中间的图形肯定是大量重复的,乘一下就知道贡献,只有开始和结束不同。问题是怎么写比较方便比较快…

  只要判断一下每次操作完和操作前是不是一样的就能判断出开始重复了,所以非常好写。复杂度 $O(n^3)$。

2017-06-21


TC SRM 565 div1 Hard  Unknown tree

  题意:

  一棵 $n+3$ 个点的无根树,编号 $0,1,\cdots,n-2,n-1,A,B,C$,每条边边权是正整数,现在给定前 $n$ 个点每个点分别到 $A,B,C$ 三点的距离 $d_A[],d_B[],d_C[]$,求满足条件的树的个数。

  数据范围:$n \leq 50, \forall i, 1 \leq d_A[i],d_B[i],d_C[i] \leq 10^8 $

  题解:

  分类讨论大乱搞…首先从只有一个特殊点 $A$ 的距离限制时开始考虑怎么做。如果这样的话,我们把 $A$ 当做根,那么每个点可以任选一个距离严格小于它自己的点当父亲。注意到父亲关系不会相互影响,所以方案数就是每个点的可能父亲数的乘积。

  现在加到两个点,那么注意到树上点分为两类,一类是在 $A \leadsto B$ 的路径上,一类是在其它位置。而在路径上的点的位置是已经确定的,剩下的点和刚才一样做就好了(现在变成了距离严格小于它并且离 $A,B$ 两点距离变化量相等的点可以作为父亲),不过注意一个点的父亲可以选择 $A,B$ 中的点。于是现在问题是如何确定在路径上的点。有一种方法是定一个点作根,然后以它作为其它点的判据,不过实际上可能根本不存在一个在路径上的点,那么就需要进行各种分类,所以这种方法不方便。另一种方式是直接枚举路径的长度,观察哪些长度是可能的,每个点按照它可能的位置不同会提供两种长度,分别是到两个点距离的和与差。于是总共可能距离有 $O(n)$ 个,枚举一下,以此为依据检查剩下的点是否合法(需要额外注意因为边权是正整数,所以路径上不能有到一侧点距离相同的两个点,下同),然后计数即可。

  最后我们回到原题,如果有三个点怎么办。这样按照它们的位置关系有两大类,一类是三条它们两两间的路径交于一个点,一类是其中一个点在另外两个的路径上。

  对于第一种情况,我们可以以这个点为根,记为 $r$,然后判断出 $r \leadsto A, r \leadsto B, r \leadsto C$ 三条路径上的点,剩下的点还是按照最初的方法统计父亲数。

  对于第二种情况,假设中间点是 $B$,我们沿用上面枚举的办法,现在每个点可以提供四组有序对 $( d_{AB},d_{BC} )$,分别就是距离和与距离差的情况。然后就基本一样了。

  整体来说情况不算复杂,而且判断的地方附加大量冗余判断也不会影响正确性,所以把考虑到的情况都写了基本就行了…复杂度 $O(n^2 \log n)$

TC SRM 567 div1 Medium  String game

  题意:

  给出最多 $50$ 个长度至多 $50$ 的小写字母串。第一个人选出一个字符串 $X$,任意重排,并任意指定字母表的大小顺序,第二个人任意重排剩下的字符串。第一个人赢当且仅当按照这个字母表的顺序, $X$ 重排后字典序严格小于重排后的其他字符串。假设两人取最优策略,问第一个人选哪些 $X$ 能赢。

  题解:

  显然重排就是把小的放前面,所以等价于按字典序比较字符个数。注意到如果没有个数相同比较下一位这个因素的话结果是直接确定的,比第一位就好了。而有个数相同的因素的话,可以看作被延迟比较。

  考虑一个能让第一个人赢的字母表,对于每一位都保证还没有比出结果的其它串的这个位的字符个数不超过 $X$的。如果把字母表中一个字母提到最前,如果不会导致其它串直接超过 $X$ 的话,作用其实就是把延迟的比较提前,最终还是能让第一个人赢。这就意味着,如果第一个人能赢,我们随便枚举满足“不会让其它串直接超过 $X$”的下一位,就一定能顺着得到整个字母表;而如果某一位找不到下一位,则第一个人必输。所以直接这么做就好,复杂度 $O(n^2 26^2)$

2017-06-22


TC SRM 575 div1 Medium  TheSwapsDivOne

  题意:

  给定一个长度至多 $2500$ 的数字序列和一个操作次数 $k$,每次操作随机选取一对两个不同位置的数交换。求操作完后随机取一个区间的区间和的期望。

  数据范围:$k \leq 10^6$

  题解:

  操作过程和最后算答案的部分是独立的,所以可以算出每个位置出现在区间中的概率,然后乘以对应位置的期望值得到答案。所以问题变成如何求一个位置的数的期望。

  某个位置的数的期望可以由所有位置经过 $k$ 次操作后达到这个位置的概率算出。显然可以有一个暴力的 $k^3$ 的DP做法,$f_{i,j,k}$ 代表第 $i$ 轮原来第 $j$ 个数到达位置 $k$ 的概率。

  但是这个不能满足要求。不过可以发现操作的过程具有对称性,即原来的任何一个位置的地位是相同的(可以直观地感受到,也可以通过这个暴力DP得到)。每个位置的数到达任何一个其它位置的概率都是相同的(但是不一定和留在原地的概率相同),并且对于所有数来说这个概率也都相同。

  所以可以直接设 $f$ 表示某一个数操作后到达某一个确定的不与初始相同的位置的概率,$g$ 代表某一个数操作后留在原地的概率。显然初始 $f=0,g=1$,每次操作的转移是 $f' \Leftarrow \binom{n}{2} \left( f(n-2)+g+f\binom{n-1}{2} \right)$,而根据定义有$g = 1-(n-1)f $。所以直接 $O(k)$ 递推即可通过本题。

TC SRM 578 div1 Hard  DeerInZooDivOne

  题意:

  给定一棵 $n$ 个点的无根树,求两个不相交连通块,要求满足它们点集的生成子图同构,且大小尽可能大。输出大小。

  数据范围:$n \leq 50$

  题解:

  看起来很厉害的一道题(看到同构就觉得很厉害啦啦啦)

  假如现在有两棵有根树,它们的根分别为 $a,b$,设 $f_{a,b}$ 表示它们互为同构映射的对应点的时候的最大的包含它们的同构连通块大小。

  那么有 $ f_{a,b} = 1+Max \left\{ \sum_{x \in son_a,\tau(x) \in son_b} f_{x,\tau(x)} \right\} $,其中 $\tau(x)$ 是一个从 $son_a$ 到 $son_b$ 的一一映射(如果一方不够的话可以补上空点)。

  最大化这个东西的话,就是一个二分图最大权匹配了。写正版的KM就能 $O(n^3)$ 完成转移。

  假设我们不用担心时间复杂度,我们就可以先放心地选一条边把树剖开,然后在两边枚举两个根来做这个DP。

  这样子的复杂度是多少呢?枚举边 $O(n)$,枚举两个根 $O(n^2)$,DP状态 $O(n^2)$,转移 $O(n^3)$,那么就是 $O(n^8)$ 哒(雾)。

  嗯…如果DP状态用边来表示(用$f_{a,fa,b,fb}$表示,其中$fa,fb$表示$a,b$的父亲)的话,算上枚举也只有 $O(n^2)$ 的状态。于是现在就变成 $O(n^6)$ 了。

  (但是后面的转移的 $n$ 的总和也是不明显地达到 $n^2$ 级的,比如考虑星型树,所以似乎也不能很安全地再把界放下去,虽然这些被拆得很散会导致 $O(n^3)$ 非常小)

  我造了各种星型树拼凑的数据都无法让程序慢过50ms…可能有别的分析方法可以得到更紧的界,可能是数据水,也可能只是数据造不满…总之我只能得到 $O(n^6)$ 的界了。

  于是就这么轻松跑了过去,我人傻就只能当这个是玄学了。(TC上最慢只有十几毫秒)

/**

  todo:

  PE 427 n-sequances

  PE 295 Lenticular Holes

  PE 434 Rigid Graphs

*/