Codeforces乱写
CF1493F
考虑如下事实:将小矩形 \((x,y)\) 合法等价于 \((x,m),(n,y)\) 合法
所以可以把矩阵拍到序列上做,两维的合法答案乘积就是总答案,那么考虑序列问题如何求解
朴素的 \(\rm{KMP}\) 求 \(\rm{period}\) 的思想是找 \([1,n-l+1],[l,n]\) 判等以得出 \(l\) 是长度为 \(n\) 的串的 \(\rm{period}\),但是在本题中不能相交
但是如果一旦得到有同构的矩形那么完全可以直接在循环节中完成询问,每次试除长度的质因子即可,询问次数不超过一个 \(\log\)
对于没有找到循环节前的询问,设质因子将序列分成了 \(m\) 段
-
\(m\) 是奇数时分两次询问:让 \([m/2+2,m]\) 做桥求是不是满足 \(\rm{seq[1\dots m/2]=seq[2\dots m/2+1]}\)
-
\(m\) 是偶数直接左一半和右一半是否相等即可
CF1481F
直接贪心的策略是让每层的颜色都一样,该策略能带来的答案下界是 \(\rm{\max\{dep\}}\)
考虑如下构造方式能带来的答案上界:
让剩余颜色较多的一种颜色覆盖当前层,如果不能完整覆盖一层,优先覆盖非叶子节点
不难发现非叶子节点是一定能覆盖完的,同时只有一行会遇到不能覆盖完的窘境,后者可以通过调整来得到
那么上界理所当然地变成了 \(\rm{\max\{dep\}}+1\),非常优美
对于判断答案能不能不加一地尝试,直接有一个 \(\Theta(n^2)\) 的 \(\rm{DP}\)
但是可以把层上点数相同的层合起来做,这样子复杂度变成了 \(\Theta(n\sqrt n)\)
注意根本不需要单调队列优化这个多重背包就能是这个复杂度,输出方案记录前驱即可
CF1477D
对于度数是 \(n-1\) 的那些点必然满足将有向边定向之后拓扑序相同
考虑如下事实:对于一个满足有一个点和其它所有点都没有连边的集合,将中心点在两个拓扑序中放到 \(1,|S|\),剩下的放到 \(i,i+1\),是满足条件的
那么不难发现可以将度数不为 \(n-1\) 的所有点划分成若干集合,使得每个集合都有一个点和其余所有点没有连边
具体而言,对于一个不属于任何一个集合的点 \(x\),找到一个不和它相连的点 \(y\)
-
如果 \(y\) 不属于任何集合,那么将 \(\{x,y\}\) 作为一个新集合
-
如果 \(y\) 在其集合里面是中心点,那么直接将 \(x\) 加入该集合
-
如果 \(y\) 所在的集合大小为 \(2\),将集合中心点修改为 \(y\) 后将 \(x\) 加入
-
不符合以上的,将 \(y\) 从其原始集合删去,和 \(x\) 另立山头即可
以上操作均使用 std::set
维护即可
CF1344E
下文用重边来表示非叶子节点连向其指向的点的边
对于一条路径,每个非重边需要改变方向,而可以改变方向的时间是自己最后一次改变方向到当前需求这个区间之内
如果得到了所有的区间,是否存在能让火车不自爆的方案是 \(trivial\) 的:
按照左端点排序,每个时间节点让所有合法区间中右端点最小的那个挪就行
注意如果没有合法解,那么对于右端点大于当前时间的区间也可以放弃满足来减少挪动重边的次数
剩下的问题就是求出所有区间,发现由重边连成的联通块是一个 \(\rm{LCT}\) 状物,那么每次给当前 \(\rm{splay}\) 打一个当前出现标记,计算最后一次挪动时间可以用标记加上深度来做
WF2015 Qanat
发现流向两边的土一定存在一个分界点,其就是将两边的井高和中间距离展开形成一个线段之后的中点,而这个中点必然在三角形的底边上
那么直接把题里面给的式子写出如下:
不难发现现在要做的就是最小化一个 \(f(x_1,x_2,\dots x_n,x_{n+1})\),其中 \(x_{n+1}=w\)
把 \(x_1\) 作为主元时,式子是一个二次函数,可以求出来在式子取到最小值时 \(x_1\) 和 \(x_2\) 的关系,不断迭代就能得到整个函数的解
所以本题想到 变量主元 就能迎刃而解了
CF1142D
在合法序列中第 \(i\) 个数字后面加入一个 \(c(c<i\%11)\) 字符,新的字符的排名为
即在 \(i\) 个数字前面的数字加入数字后都比 \(i\) 大,\(1\sim9\) 要计算其本身,\(c+1\) 为这个数字自己加的部分
那么将 同余部分扩展:该排名 \(\mod 11\) 的余数即:
那么定义 \(dp_{i,j}\) 表示以 \(i\) 结尾的子串中排序 \(\mod 11=j\) 的数量,转移是平凡的
CF1028G
先求一个 \(len_{i,j}\) 表示当前剩余 \(i\) 次询问,首次询问的数字数量是 \(j\) 的最大求出长度
转移考虑枚举每个询问的数字,同时注意后面询问可选的数字数量和这次查询有关,那么加入的 \(len_{i-1,* }\) 的第二维要实时变化
这东西直接做是 \(4\times (10^4)^2\) 的,但是注意询问个数上界是 \(10^4\),满了之后集体统计
具体交互直接按照题目和 \(len\) 的信息模拟即可,注意两部分都需要加上询问数自己的贡献 \(1\)
CF1458F
这题标签最关键的一个应为 \(\rm{Divide \ and \ Conquer}\)
想到分治,即统计跨过 \(\rm{mid}\) 的线段的答案之后考虑如何合并快速求解 \(\rm{\sum_{j\in[mid+1,r]}Con{[l,mid]}\ \cup\ Con[mid,j]}\)
传统的合并直径的方法在这里会遇到巨大障碍,那么考虑一个直径必然可以减半,即一个点集包含于一个以直径中点为圆心,原直径为直径的圆
更高明的定义是该圆被称为点集的覆盖邻域
此时圆心可能是边的中点,而对于直径并不唯一的点集,所有直径的中点必然相同,这个性质的证明是平凡的
对于两个点集合并所能得到的圆只有两种情况:
-
包含:条件和初中数学所学一致,只不过本题是树上距离罢了
-
相交/切/离:求出圆心距,从 \(c_1\) 出发沿着圆心之间的路径走 \(\rm{\frac{dst+r_2-r_1}2}\) 就是新的圆心,半径是 \(\rm{\frac{dst+r1+r2}2}\)
乍一看貌似非常不负责任,坐标系上的运算和树上路径貌似混为一谈了
但观察对覆盖邻域的定义,这里的树上简单路径的长度和笛卡尔坐标系上的点点距离是完全一致的
那么可以处理 \(\rm{y\in[mid+1,r],Con[mid+1,y]}\),每次枚举左端点之后,右端点可以分成三段:左包含右,两侧相交,右包含左
第二个本质把距离式子拆开后变成了 \(\texttt{「LNOI2014」 LCA}\)
实现的时候把边也表示成点来避免直径不在端点处的巨大多分类讨论
CF1446C
有点回归思维竞赛的题目呀,先观察一波这个图到底长什么样子?
如果有两个点 \((x,y)\) 的异或值是全局最小,就直接拿出,发现 \(x,y\) 不会再和其它点有边
对此进行归纳表明每个联通块里面都不会有大小超过 \(2\) 的简单环
不难想到把所有点扔到 \(\rm{trie}\) 树上跑,然后发现如果两个儿子的 \(\rm{size}\) 都大于 \(1\) 就不能联通
到这里,正解还没有呼之欲出吗?没错,就是 \(f_i=\max(f_{i\to ls},f_{i\to rs})+1\)
加一是表示只剩下这个点的时候能和另一个儿子进行连边
记得如果只有一边的儿子直接继承就行了
CF1446D
看一会,再看一会就能发现满足条件的最长的子段的众数之一必然是序列众数 \(x\)
正确性直接考虑如果不是的话可以扩展到序列众数出现相同次数
如果序列不止一个众数答案就是 \(n\),反之枚举另一个众数 \(y\)
把 \(a_i=x\) 的地方置 \(1\),\(a_i=y\) 的地方置 \(-1\),其它位置为\(0\)
找到最长和为 \(0\) 的子段就是可能答案
那么 \(\rm{Easy\ Version}\) 就可以通过了,但是困难版并不行
思考一下哪些工作是重复的呢?
那些出现次数比较少的数字重复枚举了很多次 \(b_i=0\),考虑使用根号分治优化这个过程
出现次数 \(\ge \sqrt n\) 的直接暴力
出现次数少的部分一起扫,枚举一个众数出现次数,伴随区间右端的移动,左端也是单调不降的
CF920E
142857cs 的思路属实有趣!
求补图的联通块个数的做法貌似不胜枚举,考虑必然存在一个点满足没有删除的边小于 \(m/n\) 条
也就是说把这些点扒出来跑并查集暴力就可以得到一个复杂度合法的做法了
CF1515E
看数据发现是个区间 \(\rm{DP}\),再看一会发现每个区间区间之间没有区别
使用 \(f[i][j]\) 表示一个长度为 \(i\) 的区间使用 \(j\) 次人工点亮的方案数,那么答案就是 \(\sum f[n][i]\)
乍一看这个转移可能是二维卷积其实不然,我们必须亲定两个没有夹着的点被手动点亮过
如果全部手动点亮一个长度为 \(i\) 的序列,考虑随便选一个点每次往左边或者右边都可以,方案数是 \(2^{i-1}\)
那么转移考虑枚举左/右边手动打开的连续段长度,也就是:
CF1515F
套用 \(\texttt{NOI2020 Day2 T1 制作菜品}\) 的结论,如果 \(\sum v_i<(n-1)x\) 则无解
同时可以归纳证明 \(\rm{sum\ge(n-1)x}\) 的时候就一定有解,构造方式也很类似
首先找到图上任意一个生成树,\(\rm{dfs}\) 整棵树
当前点点权大于 \(x\) 的边直接拆掉,给父亲点贡献,反之就可以留到最后,直接两个指针往 \(ans\) 数组里面添值即可
正确性貌似容易证明
CF1515G
每个点可以重复经过呢
如果走出强联通分量就一去不复返了,所以先求出来所有 \(\rm{scc}\)
对每个 \(\rm{scc}\) 找到任意一个生成树(\(\rm{dfs}\) 就行),剩下就是非树边的问题
如果 \(A,B\) 在同一个强联通分量里面,存在 \(A\to B\) 长度为 \(x(x<t)\) 的路径就存在 \(B\to A\) 长度为 \(t-x\) 的路径,走 \(m-1\) 次环再走回去就行
根据一些奇妙的东西,一个数 \(k\) 在模 \(t\) 意义下能表示出来的数一定是 \(\rm{gcd(k,t)}\) 的倍数,那么主要是求所有环的 \(\gcd\)
有一个非树边的简单环直接枚举能得到,对于不不止一个非树边呢?
注意到如下事实
也就是辗转相减法
那么每个不止一个非树边的环一定可以被表示为若干个环的和,那么直接 \(\rm{dfs}\) 的时候取上 \(\gcd\) 是正确的
CF1517G
注意审题:这四个点需要同时满足两个条件
看看给出的样例发现平行四边形上必然连接的是四个 \(\rm{(x,y)}\) 奇偶性互不相同的点
那么这四个点必然破坏掉一个,拆点跑最小割就行了
CF1528E
如何看待我对着这东西只想到了外向树?
条件三表示要求的是:外向树,内向树,内向树+根之间的边+外向树
下面又是 \(\rm{DP}\) 之美:先求度数小于等于 \(2\) 的部分的 \(f[i]\),且只求内向树
枚举根的前驱的情况得到一个转移:
第一项是表示根的两个儿子的深度不同,最后一个是深度相同,这里不能直接乘
中间是度数为 \(1\),那么最后纯内向/外向树的答案和上面的类似,度数为三的而已
这里不难得到根的度数只能是 \(2\) 的 \(g_i=f_i-f_{i-1}\)
注意减掉纯链的情况,此时把外向树翻转就是内向树
对于不是纯外向/内向树的图形强行钦定外向树的根的度数是 \(2\),使用 \(g_i\) 进行统计,也就是 \(\sum\limits_{i=0}^{n-1}f_ig_{n-i-1}\)
CF1528F
处理这种问题的 常见 思路是把序列新加入一个点,变成一个长度为 \(n+1\) 的环,也就是所谓的 序列转等概率环模型
对于每个新加入的 \(i\) 从 \(a_i\) 开始走,走到没有被占据的地方停,如果说最后剩下 \(n+1\) 号点没有被占据则说明序列是合法的
关注到图形变成环了,那么 每个点空出来的概率都是一样的,为 \(\frac{1}{n+1}\),这个等概率对于任意一个序列都能满足
考虑这样一个性质:将一个合法的序列每个元素 \(+1,+2,\dots +n\) 能得到一个不合法的序列,但是颜色的相对顺序不变
那么直接得到所有序列的总答案再除以 \(n+1\) 即可得到合法序列的答案
直接堆一波式子:
有没有非常熟悉?这不就是统一省选 \(\rm{2020}\ Day1T2\) 吗?
直接使用第二类斯特林数展开 \(i^k\) 然后用二项式把后面的组合数缩进去,再平移一把,把价值为 \(0\) 的数舍去就行了
最后使用 \(\rm{NTT}\) 完成一行斯特林数的计算即可