寒假集训作业题
寒假集训作业题
20210123
CF468D Tree
题意
给定一棵 \(n\) 个结点的带有边权的树,求字典序最小的排列 \(p\) 使得最大化 \(\sum dis_{i,p_i}\) ,\(n\leq 10^5\) 。
题解
转化成求每条边覆盖次数加起来,则对于一条边 \((u,v)\) ,最多覆盖 \(\min\{siz_u,siz_v\}\) 。
考虑这个上界是否能取到。可以发现是很好取到的,我们将树的根定为树的重心,则每个子树大小 \(\leq\lfloor\dfrac{n}{2}\rfloor\) ,只要对于每个点找到一个不在该子树的点即可。
由于为完美匹配考虑 \(Hall\) 定理,\(|W|\leq |N(W)|\) ,可以发现一定存在匹配。
而求字典序最小我们考虑从小到大看当前点的最小匹配,即时时刻刻 \(|W|\leq |N(W)|\) 。如果当存在 \(\forall |W|<|N(W)|\) ,则对于当前 \(i\) 我们只要找最小值。
否则 \(|W|=|N(W)|\) 时我们直接排序计算。 可以发现上述维护要维护区间最小值以及 \(|N(W)|-|W|\) ,线段树维护。
时间复杂度 \(\mathcal O(n\log n)\) 。
https://codeforces.ml/contest/468/submission/105124127
CF536D Tavas in Kansas
题意
给定一张 \(n\) 个点 \(m\) 条边的可能有自环和重边的无向连通图,每条边都有一个非负边权。
小 \(X\) 和小 \(Y\) 在这张图上玩一个游戏,在游戏中,第 \(i\) 个城市有一个权值 \(p_i\)。
开始,小 \(X\) 在城市 \(s\) 中,小 \(Y\) 在城市 \(t\) 中,两人各有一个得分,初始为 \(0\),小 X 为先手,然后轮流进行操作。
当轮到某一个人时,他必须选择一个非负整数 \(x\),以选定所有与他所在的城市的最短距离不超过 \(x\) 的还未被选定过的城市,他的得分将会加上这些城市的权值。
另外,每个人每次必须能够至少选定一个城市。
当没有人可以选择时,游戏结束,得分高者获胜。
现在请你计算出,在两人都使用最佳策略的情况下,谁会获胜(或者判断为平局)。
\(n \le 2 \times 10^3\),\(m \le 10^5\),\(|p_i| \le 10^9\)。
题解
对于每个点 \(i\) 求出 \((dis_{S,i},dis_{T_i})\) ,将其映射到网格图中,则当前问题转化成小 \(X\) 取行,小 \(Y\) 取列,每次必须有数被选择(必须连续选)且最大化两人分差。
考虑 \(dp\) 推导博弈。
设 \(f_{i,j,0/1}\) 表示当前 \((i,j)-(n,n)\) 均被选完,且当前是先/后手的分差情况(小 \(X\) -小 \(Y\) 的得分)。则小 \(X\) 希望 \(f_{i,j,1}\) 最大,小 \(Y\) 希望 \(f_{i,j,0}\) 最小。
每次考虑当前行列是否有数,每次处理一行即可达到 \(O(1)\) 转移。
由于无法确定最后的先后手考虑倒推。 时间复杂度 \(\mathcal O(n^2)\) 。
https://codeforces.ml/contest/536/submission/105191921
CF763E Timofey and our friends animals
题意
给定一张 \(n\) 个点,\(m\) 条边的图,保证每个点出度 \(\leq k\) ,\(q\) 次询问仅保留 \([l,r]\) 的子图的联通块个数。
\(n,q\leq 10^5,k\leq 5\)
题解
回滚莫队模板题。
可以想到用可撤销并查集维护莫队,但是普通莫队无法做到对于 \(l\) 指针撤销的操作,即 \(l++\) 。
那么通过回滚莫队,我们对于询问还是按照普通莫队排序,但是我们求询问时 \(r\) 还是递增,但是 \(l\) 每次从块末暴力加入。
由于 \(l\) 每次操作最多移动 \(\sqrt{N}\) 次,则时间复杂度为 \(\mathcal O(m\sqrt{n}\log n)\) 。
https://codeforces.ml/contest/763/submission/105138713
20210124
CTSC2017 吉夫特
题意
给定一个长度为 \(n\) 的数列 \(a\) ,求有多少个长度大于等于 \(2\) 的子序列 \(a_{b_1},a_{b_2},…,a_{b_k}\) 满足 \(\prod_{i=1}^{k-1}\dbinom{a_{b_{i}}}{a_{b_{i+1}}}\mod 2>0\) 。
\(n\leq 211985,a_i\leq 2333333\) 。
题解
若 \(\dbinom{x}{y}\) 为奇数,则 \(y\) 在二进制下是 \(x\) 的子集,即 \(x\&y=y\) 。证明考虑 \(Lucas\) 。
则我们只要 \(\forall i,a_{b_{i+1}}\in a_{b_i}\) 即可,暴力 \(dp\) 时间复杂度 \(O(3^n)\) 貌似就过了?
考虑更优秀的做法,利用 【UNR #4】序列妙妙值 类似的技巧我们将 \(a\) 拆成前 \(9\) 位与后 \(9\) 位,维护数组 \(Sum_{i,j}\) 表示前 \(9\) 位为当前为 \(x\) ,后 \(9\) 位若为 \(j\) 符合超级的 \(f\) 之和。
转移与更新均为 \(\mathcal O(2^9)\) ,时间复杂度 \(\mathcal O(2^9\cdot n)\) 。
https://uoj.ac/submission/450493
CF838D Airplane Arrangements
题意
有 \(n\) 个位置排成一排,有 \(m\) 个人依次进场选位置,每个人一开始会选择一个方向,从左到右或从右到左,并选择一个位置,然后按他选择的方向入场并走到这个位置,从这个位置开始继续按他选择的方向走,直到遇到一个空位并坐下。如果一直找不到空位,他就会生气。求有多少种情况没有人生气。
\(1\leq m\leq n\leq 10^6\) 。
题解
模型转化,考虑成环。为了判断是否无法找到空位加入新点 \(n+1\) 插在 \(1,n\) 中。
当前问题变化成有一个长度为 \(n+1\) 的环,你每次要选择一个点以及一个方向,他会按照这个方向走到第一个还未选择的点,共选择 \(m\) 次,问有多少种方案数不会选择 \(n+1\) 。
由于总方案数为 \((2(n+1))^m\) ,而选择到 \(n+1\) 的概率由于环上的每个点等价于是每个点被选择的概率均为 \(\dfrac{m}{n+1}\) 。
则总方案数为 \((2(n+1))^m\cdot (1-\dfrac{m}{n+1})\) 。
https://codeforces.ml/contest/838/submission/105207554
LOJ575 不等关系
题意
一个长度为 \(n\) 的排列,相邻两个数有 \(>\) 或者 \(<\) 的限制,求有多少种满足要求的排列。 \(n\leq 10^5\) 。
题解
考虑将 \(>\) 的容斥掉,将其看成无这条边或为 \(<\) 。根据容斥原理方案数可以写成:至少 \(0\) 个不符合 - 至少 \(1\) 个不符合 + 至少 \(2\) 个不满足…
那么现在我们只要讨论断掉 \(>\) 或者将 \(>\) 改为 \(<\) 的情况数。
而对于 \(k\) 个长度分别为 \(s_1,…s_k\) 的均为 \(<\) 的链,方案数可以写成 \(\dfrac{n!}{\prod s_i!}\)。
我们设 \(f_i\) 表示当前添了前 \(i\) 个数的方案数,我们枚举当前联通块,容斥系数动态计算
\(C_i\) 表示前 \(i\) 个数中的大于号个数。
很明显该式子可以分治 \(NTT\) 优化 ,时间复杂度 \(\mathcal O(n\log^2 n)\) 。
20210125
多校省选 春节
题意
给定一个二分图,其中只能用最多 \(k\) 种颜色取染边,需要求出一种边被染的最多的方法使得对于任意一个点都无法被两个相同颜色的边覆盖。
\(n\leq 200,k\leq 20\) 。
题解
和 \(CF600F\) 类似,任意一个二分图,最大度数为 \(k\) 的时候能够被 \(k\) 染色。
那么第一问我们只需要求出选择最多的边使得任意点的度数 \(\leq k\) ,显然跑最大流即可。
第二问直接按照 \(CF600F\) 构造就行啦
http://47.92.197.167:5283/submission/39921
CF1473G Tiles
题意
给定长度为 \(n\) 的序列 \(a,b\) ,我们通过一下方式构造矩形。当前第一列有一块砖,之后 \(a_i\) 列每次加一块砖,然后 \(b_i\) 列每次减一块砖。对于每列砖的块长是相同的。
问从第一列走到最后一列的方案数。 \(n\leq 10^3,1\leq a_i,b_i\leq 10^5,|b_i-a_i|\leq 5\) 。
题解
我们将其看成一个网格图,那么对于 \(a_i\) 来说是可以往右或右上走,对于 \(b_i\) 来说可以往右或右下走(实际上是可用面积的减少)。
由于
\(|b_i-a_i|\leq 5\) ,那么当我们做完一次 \(a_i+b_i\) 后长度最多增加 \(5\) ,则我们设 \(f_{i,j}\) 表示当前做完第 \(i\) 次操作,且当前在第 \(j\) 列的方案数。
计算上述式子为 \(\mathcal O(n^3)\) 的,而
\(NTT\) 计算即可,时间复杂度 \(\mathcal O(n^2\log n)\) 。
https://codeforces.com/contest/1473/submission/105274059
CF1320E Treeland and Viruses
题意
有一棵有 \(n\) 个节点的树,\(q\) 次询问(询问互相独立),每次给定 \(k_i\) 个颜色,每个颜色有一个起始点 \(v_j\) 和移动速度 \(s_j\),每一个颜色在每一次操作中会使它周围没有被染色的连通块上与它的距离不超过 \(s_j\) 的点全部染为这一个颜色,每一轮中,颜色从 \(1\) 到 \(k_i\) 依次开始操作,一直到所有点全部被染色为止,再询问 \(m_i\) 个关键点的颜色。
\(1\leq n,q,\sum k,\sum m\leq 2\times 10^5\)
题解
由于 \(\sum k,\sum m\leq 2\times 10^5\) ,考虑虚数维护关键点,由于联通块的性质,那么我们只要考虑每次虚树的情况。
那么其实问题转化成类似多源最短路的问题,\(dijkstra\) 维护即可。 时间复杂度 \(\mathcal O(n\log n)\) 。
https://codeforces.com/contest/1320/submission/105292519
20210126
省选联考 2020 A 作业题
题意
求
\(n\leq 30,m\leq \dfrac{n(n-1)}{2},1\leq w_i\leq 152501\) 。
题解
显然后面的可以反演掉。
则只需要求
考虑如何求权值为 \(d\) 的生成树权值总和,一般的 \(\text{Matrix Tree}\) 定理求的是生成树权值乘积的和。
那么我们把 \(1\) 改成 \(1+wx\) ,最后只要知道一次项系数。只要在每个点维护个在 \(\pmod {x^2}\) 单项式消元就好啦。
单项式求逆可以写成 \((a+bx)(a’+b’x)\equiv 1\) ,则 \(aa’=1,ab’+ba’=0\) ,解方程即可。
时间复杂度 \(\mathcal O(144n^5)\) ,但是边不足 \(n-1\) 条无法构成树,那么判断一下时间复杂度即为 \(\mathcal O(144n^4)\) 。
https://uoj.ac/submission/450878
Luogu4389 付公主的背包
题意
有一些物品,体积为 \(i\) 的物品有 \(a_i\) 种,每种物品无限多,物品体积最大为 \(n\) 。对于 \(1\sim m\) 中的每个数 \(k\) ,求出选出一些物品使得它们的总体积恰好为 \(k\) 的方案数。
\(n,m\leq 10^5\)
题解
将答案写成 \(\text{OGF}\) 的形式,则
由于是 \(\prod\) 考虑求 \(\ln\)
将右面泰勒展开
由于我们只要算到 \(x^m\) 那么暴力计算 \(\ln f(x)\) 的时间复杂度为 \(\mathcal O(m\ln m)\) 的。
计算多项式的 \(exp\) 就可以得到 \(f\) 。时间复杂度 \(\mathcal O(n\log n)\) 。
https://www.luogu.com.cn/record/45558166
多校省选 松鼠串门
题意
给一棵 \(n\) 个点的带点权的有根树,支持两种操作:
修改:添加一个叶子
查询:对于某个点到其祖先的路径上的所有点构成的集合,求一个子集使得子集中的点的点权异或和最大
共 \(q\) 次操作,与 \(n\) 同阶。 \(n,q\leq 5\times 10^5,a_i<2^{64}\)。
题解
可以倍增合并线性基,时间复杂度 \(\mathcal O(n\log n \cdot 64^2)\) ,但通过不了本题。
考虑如何避免合并,而且本题的路径没有拐弯。考虑一种贪心维护线性基的方式。
对于一个点,保存当前点到根所有点构成的线性基,并维护提供该向量的最低深度。
那么如果当前向量为空,直接插入。否则比较二者的深度,进行替换。
查询时仍高位至低位贪心,考虑合法向量。
时间复杂度 \(\mathcal O(64n)\) 。
http://47.92.197.167:5283/submission/40126
20210127
CF538G Berserk Robot
题意
有一个机器人,第 \(0\) 秒时在 \((0,0)\) 位置。
机器人会循环执行一个长度为 \(l\) 的指令序列,每秒执行一个指令。
指令有 ULDR
四种,分别代表向上/左/下/右移动一格。
你不知道这个指令序列具体是什么,但是你知道 \(n\) 条信息,第 \(i\) 条信息为「第 \(t_i\) 秒时机器人在 \((x_i,y_i)\)」,保证 \(t\) 递增。
你需要构造一个满足这些信息的指令序列,或判断不存在。
\(n \le 2 \times 10^5\),\(l \le 2 \times 10^6\),\(t_i,|x_i|,|y_i| \le 10^{18}\)。
题解
细节题目。考虑将坐标轴旋转 \(45\) 度后两维独立,那么现在只要考虑一维每次 \(+1,-1\) 的构造。
由于操作是一个循环,我们考虑记录前缀和 \(S_i\) 。
那么一个操作就可以看成 \(A_iS_n+S_i=B_i\) ,其中 \(i\) 表示在 \(n\) 条信息中存在一条使得其在以 \(l\) 为循环节在第 \(i\) 位。如果我们知道 \(S_n\) 那么其他的就很好还原。
若存在两个信息拥有相同的 \(i\) 那么就可以直接求出 \(S_n\) ,否则我们考虑相邻两项解 \(S_n\) 的范围,可以发现这样是充要的,解方程求 \(S_n\) 的范围即可。注意 \(S_n\) 的奇偶已经确定。
细节较多~ 时间复杂度 \(\mathcal O(l)\) 。
https://codeforces.ml/contest/538/submission/105564042
CF578E Walking!
题意
给定一个长度为 \(n\) 的只包含 L,R
的字符串 \(s\)。
构造一个 \(n\) 排列 \(p\) 满足 \(s[p_i] \ne s[p_{i+1}](1 \le i< n)\)。 最小化 \(p\) 中 \(p_i > p_{i+1}(1 \le i < n)\) 的数量。
\(n \le 10^5\),数据保证有解。
题解
可以将问题转化求最少要分成多少个 \(L,R\) 交替的子序列。
答案的下界显然是直接贪心的情况,考虑该下界如何取到。设贪心序列中开头为 \(L\) ,末尾为 \(L\) 的设为 \(LL\)。
那么 \(|LL-RR|\leq 1\) ,可以直接构造。
但是存在 \(LR,RL\) 的情况,若二者仅存在一种也很好构造 \((R…RL…RL…L)\),或存在 \(LL,RR\) (\(L…RL…LR…L\))。
我们取一个 \(LR,RL\) 中末尾最后一个比较下标放置在另一个中就可以生成一个 \(LL\) 与 \(RR\) 啦。
https://codeforces.ml/contest/578/submission/105527684
CF1267G Game Relics
题意
现在有 \(n\) 种圣物,其中第 \(i\) 个圣物的价格为 \(c_i\) 碎片。你想把这 \(n\) 种圣物全买一遍,其中有两种购买方式:
花费 \(c_i\) 碎片购买第 \(i\) 种圣物。
花费 \(x\) 碎片进行抽奖,可以等概率随机获得这 \(n\) 种圣物中的一种,如果获得了已经获得过的圣物,则会还给你 \(\frac{x}{2}\) 碎片。
现在求最优策略下,得到这 \(n\) 种圣物的最小期望花费。
\(n\leq 100,x\leq c_i\leq 10^4,\sum c_i\leq 10^4\) 。
题解
操作序列肯定是先抽奖到一定时候在把其他物品购买,因为 \(x\leq c_i\),那么抽什么都比购买优的,为了减少重复概率故先抽。
故我们将购买也看成随机在还未获得的物品中选择一个。这样我们考虑问题的子集都是等概率出现的。
那么我们考虑当前剩 \(i\) 张牌没抽,考虑第 \(i\) 张牌是抽奖还是购买,那么获得在抽奖中获得该张牌的期望次数为 \(\dfrac{i}{n}\) 。
\(\dfrac{i}{n}\) 可以看成几何分布,求法根据 \(\sum_k (1-p)^{k-1}\cdot p\cdot k=\dfrac{1}{p}\) 求得。
那么获得新牌的花费是 \((1+\dfrac{i}{n})\cdot \dfrac{x}{2}\) 。
现在考虑花费的情况,我们设当前还剩 \(sum=\sum c\) 还未选择,那么我们期望花费 \(\dfrac{sum}{i}\) 去获得其中一个。
那么我们只要决策当前是随机购买最优还是花费最优即可。实现是我们可以预处理当前选择 \(i\) 个,其中和为 \(j\) 的次数。
时间复杂度 \(\mathcal O(n^2\sum c)\) 。
https://codeforces.ml/contest/1267/submission/105581883
CF1392H ZS Shuffles Cards
题意
有 \(n+m\) 张牌,其中前 \(n\) 张牌上分别标着 \(1,2,\cdots,n\) 的数字,后 \(m\) 张牌是鬼牌。现在我们打乱这些牌,然后开始抽牌游戏,每一轮你可以抽一张牌:
如果抽到了一张标有数字 \(x\) 的牌,就移除这张牌,并将 \(x\) 加入一个集合 \(S\) ;
如果抽到了鬼牌,就把移除的牌重新加入牌堆,再次打乱所有牌的顺序,重新开始抽牌。如果你抽到了鬼牌,并且集合 \(S\) 已经包括了 \([1,n]\) 中全部 \(n\) 个数,那么抽牌游戏结束。 询问抽牌游戏结束的期望轮数。
\(1\leq n,m\leq 2\cdot 10^6\) 。
题解
可以将答案看成 每轮期望次数乘期望轮数(\(E(AB)=E(A)\cdot E(B)\) ,\(A,B\) 独立)。那么只要分别求解相乘即可。
每轮期望次数可以写成
可以 \(\mathcal O(n)\) 计算得到。
期望轮数我们考虑 \(dp\) ,设 \(f_i\) 表示当前还有 \(i\) 张牌未被选择的期望轮数。
则
其中 \(f_0=1\) 。解得 \(f_n=\sum 1+m\sum_{i=1}^n \dfrac{1}{i}\) 。
答案即为 \(f_n\cdot E\) 。时间复杂度 \(\mathcal O(n+m)\) 。
https://codeforces.ml/contest/1392/submission/105493265
20210128
CF997D Cycles in product
题意
给你大小为\(n_1\)和\(n_2\)的两棵树\(T_1\)和\(T_2\),构造一张新图,该图中每一个点的编号为\((u,v)\)。
如果在\(T_1\)中,\(u_1\)和\(u_2\)之间有边,那么在该图上,对于任意\(v\),\((u_1,v)\)和\((u_2,v)\)之间有边。同样,如果在\(T_2\)中,\(v_1\)和\(v_2\)之间有边,那么在图上,\((u,v_1)\)和\((u,v_2)\)之间有边。
问你这个图上长度为\(K\)的环有多少个,定义环为从一个点出发,走\(K\)步回到起点,可以经过重复点和重复边。
\(n_1,n_2 \leq 4000,k \leq 75\),答案对 \(998244353\) 取模
题解
我们将其看成一个 \(n_1\times n_2\) 的网格图,那么列为按 \(T_1\) 排列行按 \(T_2\) 排列。
那么可以发现行与列是独立的,即若我们从 \((i,j)\) 开始走可以看成在 \(T_1\) 的 \(i\) 走 \(k_1\) 步且回到 \(i\) 号点,从 \(T_2\) 的 \(j\) 走 \(k_2\) 步且回到 \(j\) 号点。
则 \(k_1+k_2=k\),这时的方案数为 \(cnt_1\cdot cnt2\cdot \dbinom{k}{k1}\) 。
我们只需要知道对于 \(T\) 中任意一个点走 \(p\) 步走回该点的方案数。
设 \(f_{i,j}\) 表示当前在 \(i\) 号点,仅考虑该子树时走 \(j\) 步回到 \(i\) 的方案数。
我们将其写成 \(\text{OGF}\) 的形式,那么
那么就可以 \(f_{rt}(x)\) 就是根的答案,对于不是根的答案可以换根得到。
当讨论 \((u,v)\) 为我们考虑当前是以 \(u\) 为根,但要换成 \(v\) 为根的时候,由于换根影响的只要 \(f_u,G_u,f_v,G_v\) 。
可以发现
同理可推出
所以只要写个多项式求逆维护 \(f(x)\) 即可。但据说常数太大(\(k\) 才 \(75\) )改成暴力求逆时间复杂度 \(\mathcal O(nk^2)\) 。
https://codeforces.ml/contest/997/submission/105623336
CF1163F Indecisive Taxi Fee
题意
给你一个 \(n\) 个点,\(m\) 条边的无向图,每条边连接点 \(u, v\),并且有个长度 \(w\)。
有 \(q\) 次询问,每次询问给你一对 \(t, x\),表示仅当前询问下,将 \(t\) 这条边的长度修改为 \(x\),请你输出当前 \(1\) 到 \(n\) 的最短路长度。
\(n,m\leq 2\times 10^ 5\) 。
题解
我们找到一条 \(1\) 到 \(n\) 的最短路 \(L\) 。
若 \(t\in L\) ,那么若 \(x\) 比原先值只要减去减少量,而 \(x\) 比原来值大相当于讨论 \(t\) 是否选择,需要知道删去 \(t\) 这条边的最短路。
若 \(t\notin L\) ,那么我们只要考虑当前最短路与经过这条路的最小值即为答案。
那么只要知道删边最短路即可。一个做法是我们对于每条边 \((u,v)\) 找到一条 \(1\) 到 \(n\) 的最短路,将其更新在未出现在当前最短路但在 \(L\) 中的边。
我们需要证明 在删去 \((u,v)\) 后的最优路径为 \(I\) ,那么 \(\forall (i,j),(i,j)\in I\) 且强制走 \((i,j)\) 的最短路为 \(I\) 。
\(\text{dengyaotriangle}\) 的博客里给出详细证明。 https://www.luogu.com.cn/blog/dengyaotriangle/shan-bian-zui-duan-lu-wen-ti
这里给出一个简单证明,对于一个点 \(i\) 我们记向前最优为 \(pre_i\) ,向后最优为 \(suf_i\) ,向前最优指在 \(1\sim n\) 的最短路中从 \(pre_i\) 离开。
则 \(pre_1=suf_1=1,pre_n=suf_n=n\) 。这里的 \(1,n\) 表示点的编号。
那么我们将 \(I\) 中点取出,记为 \(x_1,x_2,…x_k\) ,必有 \(pre_{x_1}\leq pre_{x_2}\leq…\leq pre_{x_k},suf_{x_1}\leq suf_{x_2}\leq …\leq suf_{x_k}\) ,否则若存在 \(pre_{x_t}>pre_{x_{t+1}}\) ,我们可以选择 \(pre_{x_{t+1}}\) 的路径。
我们若可以找到 \((x,y)\) 需要满足 \(pre_x\leq i,suf_y\geq j\) 即可。
考虑对于 \(\forall p\) 不会出现 \(pre_p\geq j,suf_p\leq i\) ,证明考虑设 \(pre_p=u,suf_p=v\) ,则 \(len(1,u)+len(u,x)\leq len(1,v)+len(v,x)\) ,\(len(n,v)+len(v,x)\leq len(n,u)+len(u,x)\) 。 \(len(x,y)\) 表示从 \(x\) 至 \(y\) 的最短路。
拆开可得 \(len(v,u)+len(u,x)\leq len(v,x),len(u,v)+len(v,x)\leq len(u,x)\) 。
得 \(len(u,v)\leq 0\) ,不符合题意。 **注意,我们钦定了 \(len(n,v)=len(v,n)\) 故在有向图或带负权图中不成立(若存在 \(0\) 权边可以缩点处理) **
我们整理一下条件: \(pre,suf\) 具有单调性,\(pre_1=suf_1=1,pre_n=suf_n=n\) 且不会出现 \(pre_x\geq j,suf_x\leq i\) 的情况。
那么若 \(pre\) 跨过 \(i-j\) ,则 \(suf\) 也肯定跨过 \(i-j\) ,那么我们取 \(x\) 满足 \(pre_x\leq i\) 且 \(\max x\) 与 \(y\) 满足 \(pre_y\geq j\) 且 \(\min y\) 即可。
得证。写个扫描线维护即可。
https://codeforces.ml/contest/1163/submission/105641826
CF1463F Max Correct Set
题意
在 \(1\sim n\) 中选择尽可能多的数是的任意两个数的差不为 \(x,y\) 。
\(1\leq n\leq 10^{9},1\leq x,y\leq 22\)
题解
令 \(p=x+y\) 。
那么我们若在 \([0,p)\) 中选择的合法集合为 \(\{x_1,x_2,…,x_k\}\) ,那么在 \([p,2p)\) 中选择 \(\{x_1+p,x2+p,…,x_k+p\}\) 依然合法。(证明考虑若存在可以推导出在同组中也必定存在)
那么我们只要最大化 \([0,p)\) 就可以解决问题,因为 \(p\) 肯定是循环节否则我们可以将其对应到 \(p\) 所在的段。
只要处理出最后剩下的那点东西就行。实现时可以直接带权就可以直接处理。
https://codeforces.ml/contest/1463/submission/105665120
20210131
CF1188D Make Equal
题意
给出 $ n $ 个数字 $ a_1 , a_2 , \ldots , a_n $ ,每次操作可以给其中一个数加上 $ 2 $ 的非负整数次幂。求最少的操作次数,使得这 $ n $ 个数相等。
\(1\leq n\leq 10^5,1\leq a_i\leq 10^{17}\)
题解
题目要求最小化 \(\sum_i cnt(x+a_n-a_i)\) ,\(cnt(x)\) 表示 \(x\) 中 \(1\) 的个数。
令 \(a_i \gets a_n-a_i\) ,那么只要最小化 \(\sum_i cnt(x+a_i)\) 。
考虑按位 \(dp\) ,那么我们需要知道对于每个数 \(a_i\) 是否产生进位给它。
但我们发现进位的一定是 \(a_i\) 在模 \(2^k\) 意义下的一个后缀,\(k\) 表示当前考虑的位。
那么我们令 \(f_{k,s}\) 表示当前考虑第 \(k\) 位,第 \(k-1\) 位给第 \(k\) 位进位的位后缀 \(s\) 。
那么转移时只要考虑 \(s\) 与当前位置填 \(0/1\) 即可。时间复杂度 \(\mathcal O(n\log a_i\log n)\) 。
https://codeforces.ml/contest/1188/submission/106068849
CF788E New task
题意
有一个长度为 \(n\) 的数列 \(a_i\),还含有 \(b_i\in\{0,1\}\)。\(m\) 次操作,分为两种:
- \(1 \space x\) :令 \(b_x=0\)
- \(2 \space x\) :令 \(b_x=1\)
每次操作后输出满足条件的 \(p_1<p_2<p_3<p_4<p_5\) 满足 \(a_{p_1} \le a_{p_2} =a_{p_3}=a_{p_4} \ge a_{p_5}\) 且 \(b_{p_2}=b_{p_3}=b_{p_4}=1\) 的个数对 $ 10^9+7$ 取模的值。
题解
显然是考虑 \(p_2,p_3,p_4\) ,那么我们设 \(L_i=\sum_{j=1}^{i-1} [a_j\leq a_i],R_i=\sum_{j=i+1}^n [a_j\leq a_i]\) ,则答案为 \(L_{p_2}\cdot R_{p_4}\) 。
由于每次改动只会改变 \(b_i\) 的取值不会改变 \(L_i,R_i\) ,我们考虑求所有三元组 \(i,j,k\) 满足 \(b_i=b_j=b_k=1\) 的 \(L_{i}\cdot R_k\) 之和。
可以利用线段树维护上述操作,合并时讨论 \(i,j,k,ij,jk,ijk\) 分别的贡献即可。
https://codeforces.ml/contest/788/submission/106065621
CF930E Coins Exhibition
题意
求在一个长度为 \(k\) 的 \(0/1\) 序列中符合 \(q\) 个条件的方案数。每个条件形容 \([l,r]\) 至少有一个为 \(0\) 或至少有一个为 \(1\) 。答案对 \(10^9+7\) 取模。
\(k\leq 10^9,0\leq q\leq 2\cdot 10^5\) 。
题解
由于值域太大离散化 \(l,r\) 。那么现在只要考虑每段的情况。
设 \(f_{i,0/1/2}\) 表示当前第 \(i\) 段选择全白色/全黑色/有黑有白的方案数,且需要符合线段在 \(1\sim i\) 中的条件。
那么
\(len\) 表示当前长度。
而对于 \(f_{i,0}\) 来讲我们枚举后缀为白色的连续段,而我们可以得到 \(L_i\) 表示他往左极长连续段的大小,即到 \(L_i\) 时就必须选择黑色。
那么
同理可得 \(f_{i,1}\) 。可以发现上述过程可以通过前缀和优化,时间复杂度 \(\mathcal O(n\log n)\) 。
https://codeforces.com/contest/930/submission/106071934
20210201
CF1168E Xor Permutations
题意
给定一个 \([0,2^n)\) 的序列 \(a\) ,你需要求出是否有两个 \(2^n-1\) 的排列 \(p,q\) 满足 \(\forall i,a_i=p_i\space \text{xor} \space q_i\) ,并给出构造。
\(1\leq n\leq 12\) 。
题解
先给出做法,我们先将 \(p_i=q_i=i,v_i=p_i\space \text{xor}\space q_i=0\) ,考虑通过调整使得最后 \(a_i=v_i\) 。
当前 \(i=0\) ,若 \(a_i\neq v_i\) ,舍 \(d=a_i\space \text{xor}\space v_i\) ,将 \(v_i \space \text{xor}\space d,v_{i+1} \space \text{xor}\space d\) ,然后执行 \(fix(i,i+1)\) 操作。
\(fix(x,y)\) 表示通过调整使得 \(p_x \space \text{xor}\space q_x =v_x,p_y \space \text{xor}\space q_y=v_y\) ,而对于每次需要保证 \(p_x\space \text{xor}\space q_x\space \text{xor}\space v_x =p_y \space \text{xor}\space q_y \space \text{xor}\space v_y\) 。
而 \(fix(x,y)\) 的实现步骤如下
- 令 \(d=q_x \space \text{xor}\space v_x\) ,设 \(k\) 表示 \(p_k=d\) 的位置。
- 若 \(x=k\) ,那么已经符合条件,返回。
- 若 \(y=k\) ,那么 \(swap(p_x,p_y)\) ,返回。
- 否则 \(swap(p_x,p_k),swap(q_y,q_k)\) ,然后 \(fix(k,j)\) 。
我们需要证明相同的 \(p\) 仅会选择一次。
我们先将前几次的写出
我们将其写成普通形态
若同一个 \(p_k\) 再次出现
那么可以推出
则 \(q_j=q_m\) ,而 \(q\) 是个排列,矛盾。则 \(p_k\) 只能出现一次,得证。
时间复杂度 \(\mathcal O(4^n)\) 。
https://codeforces.com/contest/1168/submission/106152612
多校省选 字符串计数
题意
已知字符集大小 \(|\sum|=A\) ,计算字符串对 \((S,T)\) 满足 \(|S|=N,|T|=M\) 且 \(T\) 是 \(S\) 子串的数目。答案对 \(10^9+7\) 取模。
\(1\leq n\leq 200,1\leq m\leq 50,1\leq A\leq 1000\) 。
题解
假设我们已知 \(T\) 如何求所有的 \(S\) 。设 \(f_i\) 表示在 \(S\) 中第一次出现 \(T\) 的位置为 \([i-M+1,i]\) 时前 \(i\) 个字符的方案数,则答案为 \(\sum_{i=M}^N f_i\cdot A^{N-i}\) 。
而 \(f\) 的转移考虑若有 \(T\) 时的位置 \(j\)
其中 \(W_{j,i}\in{0,1}\) ,当 \(W_{j,i}=1\) 表示 \((j-m,j]\) 与 \((i-m,i]\) 无交或 \((i-m,j]\) 是原串的 \(border\) 。
那么若 \(border\) 集合相同的方案数是一样的,而当 \(m\leq 50\) 时本质不同的 \(border\) 集合仅有 \(2249\) 种,暴力找出。
http://47.92.197.167:5283/submission/40469
USACO 2021.1 Platinum Sum of Distances
题意
给定 \(k\) 张图 \(G_i\) ,我们构造新图 \((a_1,a_2,…,a_k)\) ,若 \((a_1,a_2,…a_k)\) 与 \((b_1,b_2,…,b_k)\) 之间有边当且仅当对于 \(\forall i,(a_i,b_i)\in G_i\) 。
\(k\leq 5\cdot 10^4,\sum N\leq 10^5,\sum M\leq 2\cdot 10^5\) 。
题解
整理一下连边可以发现 \(b\) 其实就是 \(a\) 中每个点在所属的 \(G_i\) 移动一步。那么显然我们考虑求出奇偶最短路那么对于 $(a_1,a_2,…,a_k) $ 的最短路即为 \(\min\{\max A,\max B\}\) ,\(\max A\) 表示奇最短路,\(\max B\) 表示偶最短路。
考虑求 \(\min\{\max A,\max B\}\geq k\) 的个数,容斥转化成求 \(\prod N-[\min\{A\}<k]-[\min\{B\}<k]+[\min\{\max\{A,B\}\}< k]\) 。
线段树或递推维护,时间复杂度 \(\mathcal O(m\log m)\) 。
20210202
联合省选 2020 A 树
题意
给定一棵 \(n\) 个结点的树,定义 \(val(u)=\text{xor} (\space W_v+dis(u,v))\) ,其中 \(v\) 在 \(u\) 的子树中。求 \(\sum_{i=1}^n val(i)\) 。
\(1\leq n,W_i\leq 525010\) 。
题解
方法一
本题需要支持维护合并,插入,每个点加一,求异或和的数据结构。
考虑 \(trie\) 树维护二进制,合并,插入,求异或和与线段树合并类似,而每个点均 \(+1\) 其实是让后缀的 \(1\) 变为 \(0\) ,然后将下一位的 \(0\) 变成 \(1\) 。
那么若 \(trie\) 树是从低位往高位建立那么对应的即为将左儿子与右儿子反转,然后向左儿子递归。
实现时可以多建立一位就不用考虑 \(111…11\rightarrow 100…00\) 。
方法二
一个点 \(u\) 做的贡献是他的根的链,若按位考虑可以看成有许多个区间是相同的。
可以发现如果当前考虑第 \(k\) 位那么循环节类似长成 \(00…0111…1\) ,注意有可能循环移位,其中 \(0\) 与 \(1\) 均有 \(2^{k}\) 个。
那么差分以后就仅有 \(2\) 个元素有数,他们在 \(\pmod {2^k}\) 意义下是相同的。
对应在树上即为他们在深度 \(\pmod {2^k}\) 意义下是相同的,记录一下未进入子树与进入子树分别的差分值异或即为该子树为当前点提供的差分值。
CF1476G Minimum Difference
题意
给定一个长度为 \(n\) 的序列 \(A\) ,维护一个数据结构满足修改与查询区间内每个的个数的特定信息。
\(n,q\leq 10^5\) 。
题解
对于一个序列长度为 \(l\) 其中不同元素仅有 \(\sqrt{l}\) 个,那么通过带修莫队找到 \(\sqrt{l}\) 个元素即可。
时间复杂度 \(\mathcal O(n^{\frac{5}{3}}+q\sqrt{n}\log \sqrt{n})\) ,但由于常数原因没卡过去(题解貌似是优秀的 \(\mathcal O(n^{\frac{5}{3}})\) 做法。
https://codeforces.ml/contest/1476/submission/106270004
20210203
ARC092D Two Faced Edges
题意
给定 \(n\) 个点 \(m\) 条边的有向图,判断将每条边翻转,其他边不变的情况下,图中强连通分量的数量是否改变。
\(1\leq n\leq 10^3,1\leq m\leq 2\times 10^5\) 。
题解
若存在 \(v\rightarrow u\) 的路径那么原图 \((u,v)\) 在同一强连通分量中,则若不存在 \(u\rightarrow v\) 的不经过 \((u,v)\) 路径则会增加。
若不存在 \(v\rightarrow u\) 的路径那么 \((u,v)\) 不在一强连通分量中,则若存在 \(u\rightarrow v\) 的不经过 \((u,v)\) 路径则会减少。
那么我们只要判断是否 \((u,v)\) 是否为 \(u\rightarrow v\) 的必经边。
处理这个问题很简单,我们枚举 \(u\) 正序倒序做 \(dfs\) 树,那么若 \(v\) 在正序与倒序是相同编号则是必经边。
时间复杂度 \(\mathcal O(nm)\) 。
https://atcoder.jp/contests/arc092/submissions/19892290
多校省选 采蘑菇
题意
给定一棵 \(n\) 个结点的树,每个点有点权 \(v_i\) ,设路径权值 \(V_{u,v}\) 表示在 \(u\sim v\) 简单路径上不同 \(v\) 的个数。对于每个点 \(i\) 求出 \(\sum_{j=1}^n V_{i,j}\) 。
\(1\leq n\leq 3\times 10^5,0\leq v_i\leq n\) 。
题解
果然每次只会签到题。。。
该题解是本题的线性 \(\mathcal O(n)\) 做法(其他的不会做
对于每种相同的 \(v\) 单独考虑,并将其树转成以 \(1\) 为根的有根树。
我们设当前考虑的颜色为 \(c\) ,考虑补集转换,若对于路径 \(u\rightarrow v\) 不存在 \(c\) 的话那么 \(u,v\) 一定在一个不包含 \(c\) 的连通块中。
我们只要找到对于颜色 \(c\) 的极大不包含连通块,将其减去每个点答案减去连通块个数。
那么我们只要找到所有 \(c\) 颜色的极大连通块即可,有一个很显然的是连通块一定仅包含一个根,而根的父亲的 \(v\) 一定是 \(c\) 。
现在我们已经知道每个点为根的颜色,而个数极为在该子树下做洪水填充时没有碰到 \(v=c\) 时的结点个数。
而这个显然可以记 \(tag\) 表示,需要注意一下许多颜色都有强连通块的根为 \(1\) 的个数。
http://47.92.197.167:5283/submission/40509
20210204
多校省选 石子游戏
题意
多组询问,每次给定一棵深度为 \(k\) 个完全二叉树,其中每个点有点权(表示石子个数)。现在小 \(A\) 与小 \(B\) 在树上玩游戏,每次一人需要选择一堆石子取出任意个移动他的一个儿子,若为叶子则移除,最后无法移动者输。 问小 \(A\) 在执先手的情况下第一步有多少种操作可以使他必胜。
\(k\leq 16,T\leq 10\) 。
题解
阶梯 \(\text{Nim}\) 模板题。
阶梯 \(\text{Nim}\) 形如给定一个长度为 \(n\) 的数列 \(a\) ,每次可以选择一个非空位置 \(i\) 将其在 \(a_i\) 中取出一些石子放置 \(i-1\) 中,谁不能移动谁输。
而判断先手必胜的条件是 \(\text{xor}_{i=1}^n [i\& 1] a_i\neq 0\) ,证明考虑这个判断条件是仅看奇数位置的 \(\text{Nim}\) 游戏,因为若当前操作为偶数位置那么后手可以将其再次移动到一个偶数位置。
那么对于奇偶位置讨论一下。 时间复杂度 \(\mathcal O(T2^k)\) 。
http://47.92.197.167:5283/submission/40535
CF559E Gerald and Path
题意
有 \(n\) 条线段。每条线段给定其中一端的位置及长度。求所有线段覆盖的最大长度。
\(n\leq 100\) 。
题解
先将坐标离散化,那么现在最多存在 \(3n\) 个点。
由于一条线段 \((x,s)\) 可以更新的位置为 \([x-s,x]\) 或 \([x,x+s]\) ,我们考虑设 \(f_{i,j}\) 表示当前在按照 \(x\) 排序后考虑前 \(i\) 条线段,且仅看 \([1,j]\) 时最大覆盖长度。
若对于当前线段 \((x,s)\) 为右就可以从 \(f_{i-1,x}\) 转移。
若当前线段往左可以枚举分界点 \(k\) 使得在 \([1,k]\) 中不存在超过 \(x\) 的线段,且在 \([k,i)\) 的线段均往右。
毛估估一下这样转移是最优的 ,时间复杂度 \(O(n^3)\) 。
https://codeforces.ml/contest/559/submission/106425955
20210207
多校省选 染颜色
题意
给定一棵树,每个点有颜色 \(c_i\) 。定义权值 \(w_{u,v}=\sum [c_{t_i}\neq c_{t_{i+1}}]\) ,其中 \({t}\) 为 \(u\sim v\) 的简单路径。
支持两种操作:修改一点颜色,求子树 \(u\) 内所有点 \(\sum_{v\in sub_u} w_{v,1}\) 。
\(n,q\leq 1.5\times 10^5\)
题解
定义点权 \(s_i=[c_i\neq c_{fa_i}]\) ,那么 \(w_{u,1}\) 为从 \(u\) 到 \(1\) 中所有点的 \(s\) 和。
毛估估一下发现暴力维护连续段段数不多,而每次 \(s_i=1\) 的均为连续段的顶端,用个数据结构维护一下。
时间复杂度 \(\mathcal O(能过)\) 。感觉和用 \(lct\) 维护差不多?
事实上等价于每次做 \(lct\) 的 \(access\) 操作,则连续段总数为 \(\mathcal O(n\log n)\) ,则总时间复杂度为 \(\mathcal O(n\log n)\) 。
http://47.92.197.167:5283/submission/40555
多校省选 最大割
题意
有一张 \(n\) 个点的带权无向图。对于图中任意一个点集,称所有 恰好有一个端点 在这个点集中的边集为割,割的权值为其中边的异或和。
每次动态加边,求最大割。
题解
定义一个点的点权为与它相连边的异或和,那么问题变为了求一个异或和最大的子集。
可以发现这两个问题是等价的,因为若两端均在这个集合中就被抵消掉了,否则仅出现一次。
那么问题就变为 带修改的线性基模板 。
离线方法就有很多,例如通过前面 多校省选 松鼠串门 的做法维护删除时间,或通过线段树分治做。
而带修改线性基有一个 在线做法 https://blog.csdn.net/a_forever_dream/article/details/83654397
若我们修改的 \(x\) 不在线性基中,那么我们把它修改了再试图插入线性基上。
否则我们试图把 \(x\) 消元,但是存在一个问题就是将 \(x\) 消掉后或许会有其他元素进来,那么我们需要判断为在线性基中的元素是否可以通过 \(x\) 表达,若可以表达那么不将其删去。
那么我们只需要维护每个点所对应的线性基集合。
上述过程可以用 \(\text{bitset}\) 优化,时间复杂度 \(\mathcal O(\dfrac{nml}{w})\) 。
http://47.92.197.167:5283/submission/40636
多校省选 开锁
题意
有一张由 \(k\) 个环构成的图,其中 \(\sum c_i=n\) ,求选出 \(s\) 个点每个环内均至少有 \(1\) 个点的概率。
\(n\leq 300\) 。
题解
乱入普及组题。
直接 \(dp\) 即可。可以分治 \(FFT\) 优化。
时间复杂度 \(\mathcal O(Tnk)\) 。
http://47.92.197.167:5283/submission/40559
CF1481F AB Tree
题意
给定一棵 \(n\) 个点的根为 \(1\) 的树,每个点有一个字符 \(a/b\) ,其中 \(a\) 的总数有 \(x\) 个。每个点的字符串为从根到该点的简单路径所经过的字符连成的字符串。求最少有多少个本质不同的串。
\(1\leq x\leq n\leq 10^5\) 。
题解
显然答案的下界为最大深度 \(d\) 。
而观察发现答案的上界为 \(d+1\) ,因为若取到 \(d+1\) 那么仅有一个深度有不同颜色,且分布在叶结点。
我们考虑构造证明,若当前还剩 \(k\) 个 \(a\) ,当前共有 \(m\) 个结点未染色,记当前深度有 \(z\) 个结点。
- 若 \(z\leq k\) ,那么此层均为 \(a\) 。
- 若 \(z\leq m-k\) ,那么此层均为 \(b\) 。
- 否则,我们将一个消耗完,构造方案已定。
由于若当前层非叶结点有 \(s\) 个,那么 \(s\leq \dfrac{m}{2}\) ,\(s\leq \max\{m,m-k\}\) ,说明一定存在一种方案使得非叶结点是同色的。
那么我们只要考虑答案为 \(d\) 的情况,即为深度相同的颜色均相同。
由于 $\sum=n $ ,那么不同深度的所含结点为 \(\mathcal O(\sqrt{N})\) ,\(\text{bitset}\) 优化背包。
时间复杂度 \(\mathcal O(\dfrac{n\sqrt{N}}{w})\) 。
https://codeforces.ml/contest/1481/submission/106743455
20210209
ZROI1761 环
题意
有多少个长度为 \(2n\) 的序列 \(a\) 满足,\(\forall i,a_i\in[1,m]\) 且相邻两个数差恰好为 \(1\) ,其中 \(1\) 与 \(2n\) 相邻。
对于 \(k\in[1,n]\) 均求出当 \(n=k\) 时的答案。
\(1\leq n,m\leq 10^5\) 。
题解
将问题转化成网格图上即为从 \((0,i)\) 走到 \((2n,i)\) ,每次只能往右上 \((+1,+1)\) 或左上 \((+1,-1)\) 移动一次,且不能碰到 \(y=0/y=m+1\) 直线。答案即为 \(i\in[1,m]\) 的总和。
如果说限制直线只有一条那么直接按照类似卡特兰数的计算方法计算,但是两条的就需要多考虑一些情况。
设若折线碰到 \(y=0\) 记为 \(A\) ,碰到 \(y=m+1\) 记为 \(B\) ,那么普通计算方式可以计算出存在 \(A\) 或 \(B\) 的情况,例如从 \((0,i)\) 经过 \(y=0\) 最后到 \((2n,i)\) 的方案数为 \(\dbinom{2n}{n+i}\) 。
可以发现这是一个容斥问题,我们将 \(AAABBA\) 若看成 \(ABA\) 这样进行缩点那么答案即为 \(\sum_{Q} (-1)^{|Q|} Cnt(Q)\) ,其中 \(Q\) 表示一个 \(A,B\) 交替的序列。
正确性很好理解,对于一个不合法方案,例如 \(ABA\) 可以看成 \(A/B/AB/BA/ABA\) ,其中带权为 \(+1-1-1+1+1-1=0\) ,\(AB\) 可以的权看成 \(+1-1-1+1=0\) 。
那么我们只需要计算 \(\sum_Q (-1)^{|Q|} Cnt(Q)\) 。
若 \(Q=\varnothing\) ,则即为从 \((0,i)\) 至 \((2n,i)\) ,总方案数为 \(\dbinom{2n}{n}\times m\)
若 \(Q=\{A\}\) ,则我们看成对 \(y=0\) 对称,即为 \((0,i)\) 至 \((2n,-i)\) ,总方案数为 \(2\cdot \sum_{i=1}^m \dbinom{2n}{n+i}\) ,乘 \(2\) 因为对称性 \(Q=\{B\}\) 与其对称。
若 \(Q=\{AB\}\) ,则我们按照 \(Q=\{A\}\) 类似翻折两次 (我的翻折比较奇怪第一次按照 \(y=0\) 翻,第二次按照 \(y=-m-1\) 翻。其实先按照 \(y=0\) 翻在按照 \(y=m+1\) 翻即可,但还未找到此双射) ,那么即为 \((0,i)\rightarrow (2n,i-2m-2)\) ,总方案数为 \(2\cdot \dbinom{2n}{n+m+1}\times m\) 。
update:双射找到了。考虑若先对于 \(A\) 翻在对 \(B\) 翻,那么等价于经过 \(BA\) 的折线。构造也很简单,将第一次碰到 \(B\) 后的翻折,那么就可以规约到 $ A$ 的子问题。类似的,若当前处理 \(Q\) ,那么可以归约到 \(Q’\) ,仅需要删除 \(Q\) 的最后一个元素即可 。
观察发现,\(n\rightarrow n+m+1\rightarrow n+2m+2\rightarrow…\) \(|Q|\) 为偶数均为 \(m+1\) 的等差数列,奇数也如此,证明可以考虑归纳或考虑 \(y\) 的变化量 。
那么我们把 \(2\cdot \sum_{i=1}^m \dbinom{2n}{n+i}\) 改写成 \(\sum_{i=1}^m \dbinom{2n}{n+i}+\dbinom{2n}{n-i}\) ,其余的也类似。
由于组合数上面均为 \(2n\) ,那么我们只要看下标的系数。
可以发现,当 \(i\equiv n\pmod {m+1}\) 时,系数为 \(m\) ,否则为 \(-1\) 。
那么方案数可以写成 \(\sum_{i\equiv n\pmod{m+1}} \dbinom{2n}{i}\cdot (m+1)-2^{2n}\) 。
若暴力计算时间复杂度为 \(\mathcal O(\dfrac{n^2}{m})\) ,在 \(m\) 较大时可以过掉,取分界 \(\sqrt{n}\) ,那么当前只要考虑 \(m\leq \sqrt{n}\) 的情况。
这种情况也很简单,我们维护 \(f_i\) 为一个 \(m\) 次多项式,\([x^j] f_i\) 表示 \(\sum_{j\pmod {m+1}}\dbinom{2i}{j}\) ,\(f_{i+1}\) 相当于把组合数杨辉三角一下。
时间复杂度 \(\mathcal O(nm)\) ,则总时间复杂度为 \(\mathcal O(n\sqrt{n})\) 。
http://zhengruioi.com/submission/309533
ZROI1764 基础
题意
有一个 \(2\) 行 \(n\) 列(从左到右编号为 \(1\) 至 \(n\) )的网格。每个格子里写着一个数字(可以为负数),第一行的数字为 \(A_{1..n}\) ,第二行的数字为 \(B_{1..n}\) 。
你有两只脚,分别踩在两行格子中,初始时分别在 \(A_1\) 和 \(B_1\) 。你需要通过一系列移动让你的两只脚走到 \(A_n\) 和 \(B_n\) 。在每一次移动中,你可以抬起一只脚,将它向终点移动若干格(可以连续移动同一只脚)。但是,为了避免站立不稳,你需要保证任意时刻两只脚的距离不超过 \(k\) (假如一只脚在 \(A_i\) ,另一只脚在 \(B_j\) ,则 $ |i-j|\leq k$ )。
在一种移动方案中,你得到的分数为所有被你的某只脚踩过的格子里的数字之和(包括起点和终点)。请问你可以获得的最大分数是多少。
\(1\leq n,k\leq 5\cdot 10^5,-10^5\leq A_i,B_i\leq 10^5\) 。
题解
场上一直在想 \(dp\) 缩减状态数。。。
显然正数肯定可以取完,那么我们现在仅需要考虑 \(A_i,B_i\leq 0\) 的情况。
那么我们肯定希望答案离 \(0\) 越小越好,而如何去表达这种形式呢?我们先去考虑给定双脚所踩的位置,如何判断是否存在解。
显然可以双脚交替走,每次均走能走的最远位置。如果把这种方式看成图那么 \(A_i\) 能走 \(B_{[i-k,i+k]}\) ,\(B_i\) 能走 \(A_{[i-k,i+k]}\) 。
那么问题就变为求最短路了,因为**边权均 \(\leq 0\) **,那么若最短路存在环显然不优。
由于可以看成边权相同利用并查集优化,时间复杂度为 \(\mathcal O(n\log n)\) 。
http://zhengruioi.com/submission/309506
20210210
WC2021 括号路径
题意
给定一张 \(n\) 个点 \(2 m\) 条边的有向图,图中的每条边上都有一个标记,代表一个左括号或者右括号。共有 \(k\) 种不同的括号类型,即图中可能有 \(2 k\) 种不同的标记。点、边、括号种类均从 \(1\) 开始编号。
图中的每条边都会和另一条边成对出现。更具体地,若图中存在一条标有第 \(w\) 种括号的左括号的边 \((u, v)\),则图中一定存在一条标有第 \(w\) 种括号的右括号的边 \((v, u)\)。同样地,图中每条标有右括号的边将对应着一条反方向的标有同类型左括号的边。
现在请你求出,图中共有多少个点对 \((x, y)\)(\(1 \le x < y \le n\))满足:图中存在一条从 \(x\) 出发到达 \(y\) 的路径,且按经过顺序将路径各条边上的标记拼接得到的字符串是一个合法的括号序列。
\(1 \le n \le 3 \times {10}^5\),\(1 \le m \le 6 \times {10}^5\),\(1 \le k, u, v \le n\),\(1 \le w \le k\)。
题解
可以发现
- \((u,v)\) 合法那么 \((v,u)\) 合法,满足交换性
- $(u,v) $ 合法 \((v,z)\) 合法那么 \((u,z)\) 合法,满足结合律
那么我们只要求极大联通块,其中任意两个都合法,记每个连通块个数为 \(s_i\) ,那么答案即为 \(\sum_{i} \dbinom{s_i}{2}\) 。
我们考虑将所有形如 \(()\) 的所在一个点,把这些点缩在一起会还有类似 \(()\) 这样的点,缩到不存在 \(()\) 为止。
明显这样是充要的,若存在 \((u,v)\) 合法且不在一个集合中,那么一定存在 \(()\) 没在一个集合,不合法。
而 \(()\) 这样的括号即为 \((u_1,v,k)\) 与 \((u_2,v,k)\) 。
用类似启发式合并的方式每次合并结束后将颜色集合合并下,只需要对每一种颜色记录一条出边,其余的加入队列中之后判断。
时间复杂度 \(\mathcal O(n\log n)\) ,集合要用 \(unordered\_map\) 或哈希表。
ARC101C Ribbons on Tree *
题意
给定一个大小为 \(n\) 的树,保证 \(n\) 为偶数且小于 \(5000\) 您需要给树上的点两两配对,对于一组对子 \((u,v)\),在树上将 \(u\to v\) 的路径染色,定义一个配对方案合法当且仅当所有边都有颜色。 求方案数对 \(10^9+7\) 取模。
题解
感觉和 LOJ575 不等关系 差不多,显然第一步考虑容斥。
我们将容斥时的 \(-1\) 放在 \(dp\) 里,那么我们只要合并联通块看一下是否要将当前联通块和在一起(即断掉当前点到父亲的边)。
而若连通块里有 \(s\) 个点,\(s\) 需要为偶数,那么方案数即为 \(\prod_{i=1}^s [i\&1]i\) 。
做个树形背包即可,时间复杂度 \(\mathcal O(n^2)\) 。
20200212
JLOI2015 骗我呢
题意
给定 \(n,m\) ,求有多少个 \(n\times m\) 的矩形 \(x\) 满足
- \(x_{i,j}<x_{i,j+1}\)
- \(x_{i,j}<x_{i-1,j+1}\)
- \(0\leq x_{i,j}\leq m\)
\(1\leq m,n\leq 10^6\) ,答案对 \(10^9+7\) 取膜。
题解
第一个条件告诉我们一行中的数是单调递增的,而第三个条件刻画了值域在 \([0,m]\) ,所以一行内只会缺失一个数,其余数从小到大排列。
那么我们可以通过缺失元素以及第二个条件构造矩形。
舍当前缺失元素为 \(k\) ,则当前行为 \(0,1,…,k-1,k+1,k+2,…,m\) 。
而 \(x_{i,j}<x_{i-1,j+1}\) ,那么下一行为 \(0,1,…,k-2,[k-1,k],[k,k+1],…,[m-1,m]\) ,其中 \([x,y]\) 代表可以选择的数在 \([x,y]\) 之间。
那么若当前缺失元素为 \(k\) ,那么下一行缺失元素可能为 \([k-1,m]\) 。
则设 \(f_{i,j}\) 表示当前在第 \(i\) 行,缺失元素为 \(j\) 时的前 \(i\) 行情况。
那么就得到一个 \(\mathcal O(nm)\) 的做法了。
考虑将这个式子放到坐标系内,那么问题变为了从 \((0,0)\) 走到 $(n+1,m) $ 的方案数,其中每一步能往上或右下(当 \(y=0\) 时向右)。
将 \(x+y\) 相同的归为一列重新看这个转移,并 \(f_{i-1,0}\rightarrow f_{i,0}\) 的转移由于方向为右看成先向上再往右,那么该图不存在斜方向移动的位置。
那么问题变为了求从 \((0,0)\rightarrow (n+m+1,n)\) ,且不能经过 \(y=x+1,y=x-m-2\) 直线的方案数。
按 ZROI1761 环 类似做法做即可。
时间复杂度 \(\mathcal O(n+m)\) 。
ZROI246 18AB-数对子*
题意
我们定义一个数对 \((x,y)\) 是好的,当且仅当 \(x\leq y\),且 \(x~xor~y\) 的二进制表示下有奇数个 \(1\) 。
现在给定 \(n\) 个区间 \([l_i,r_i]\),你需要对于每个 \(i \in [1,n]\),输出有几对好的数 \((x,y)\) 满足 \(x\) 和 \(y\) 都在 \([l_1,r_1] \cup [l_2,r_2]... \cup [l_i,r_i]\),即两个数都在前 \(i\) 个区间的并里。
\(1\leq n\leq 10^5,1\leq l_i\leq r_i\leq 2^{32-1}\) 。
题解
由于 \(x\space \text{xor}\space y\) 二进制有奇数 \(1\) 只有一个有奇数个 \(1\) ,一个有偶数个 \(1\) 。那么问题变为求区间交中有奇数个 \(1\) 的个数。
而对于 \([0,x]\) 中,二进制下有奇数个 \(1\) 的个数可以 \(\lfloor\dfrac{x+1}{2}\rfloor+[x\&1\space or\space cont(x)\&1]\) ,其中 \(cont(x)\) 表示二进制下 \(x\) 中 \(1\) 的个数。
证明可以考虑后缀随便填,前缀固定,由于奇偶概率均为 \(\dfrac{1}{2}\) ,那么只要考虑 \(x\) 即可。
那么直接拿线段树维护即可,时间复杂度 \(\mathcal O(32n)\) 。
20210212
CF878D Magic Breeding
题意
有 \(k\) 个长度为 \(n\) 的数组,你需要维护一个数据结构满足 \(\min,\max\) 以及求一个数组中一个下标的值。
- \(\min\) :数组 \(a\) 与数组 \(b\) 的 \(\min\) 表示成 \(c_i=\min\{a_i,b_i\}\) 。
- \(\max\) :数组 \(a\) 与数组 \(b\) 的 \(\min\) 表示成 \(c_i=\max\{a_i,b_i\}\) 。
\(n,q\leq 10^5,k\leq 12\) 。
题解
考虑仅有一个 \(0/1\) 序列的情况,那么可以设 \(f_{i,S}\) 表示在 \(i\) 数组中 \(S\) 状态下最后数是啥。
那么 \(\max\rightarrow f_S\and f_T,\min \rightarrow f_s\or f_T\) ,那么查询时只要判断一下即可。
而对于不是 \(0/1\) 序列的可以看成二分,而由于 \(k\leq 12\) 暴力即可。
由于 \(f\) 的过程可以 \(\text{bitset}\) 优化,时间复杂度 \(\mathcal O(\dfrac{2^kq}{w})\) 。
https://codeforces.ml/contest/878/submission/107249327
20210214
HNOI2019 校园旅行
题意
给定一张 \(n\) 个点 \(m\) 条边的无向图,其中每个点有点权 \(0/1\) 。\(q\) 次询问,每次询问是否存在一条 \(u\rightarrow v\) 的路径使得经过点的点权是一个回文串。
\(1\leq n\leq 5000,1\leq m\leq 5\times 10^5,1\leq q\leq 10^5\) 。
题解
一个暴力做法,每次从中间开始扩展 \(bfs\) ,每次枚举端点的出边,时间复杂度 \(\mathcal O(m^2)\) 。
考虑现在的状态 \((u,v)\) 合法,如果可以更新到 \((u’,v’)\) (不到其他颜色) ,其中 \(u\) 与 \(u’\) 在一个相同颜色集合中, \(v\) 与 \(v’\) 在同一集合中。
那么只要存在一条 \(dis(u,u’)=dis(v,v’)\) 的路径即可,实质上只要看是否存在奇偶路,即是不是个二分图(二分图仅存在一种,其他图均存在)。
那么在相同集合中可以看是否为二分图,保留其中的一棵树 \(T\) ,并且若不是随便连个自环即可改变奇偶。
而对于从一种颜色到另一个颜色也可以按上述做法做,本质是相同的。
那么边数缩减为 \(\mathcal O(n)\) 级的了,故时间复杂度 \(O(n^2)\) 。
CTSC2006 歌唱王国
题意
\(T\) 组数据,每次给定一个字符串,每次在 \(1\sim n\) 中随机一个数添加到字符串末端,当字符串出现给定字符串后停止,求期望长度。
\(1\leq n,|z|\leq 10^5,t\leq 50\) 。
题解
\(2018\space YMD\) 论文的例一,概率生成函数 \(PGF\) 的练习题。
设 \(f(x)\) 表示长度为 \(i\) 的概率生成函数,\(g(x)\) 表示长度大于 \(i\) 的概率生成函数,即未停止的概率。
则
可以看成每次从未停止中加上一次字符可能结束也可能继续。
\(a_i\in \{0,1\}\),其中 \(a_i\) 为字符串的 \(border\) 集合是否出现 \(i\) 。
可以看成我们在一个未停止串中添加当前字符串那么肯定停止,若提前停止那么即为当前串的 \(border\) 。
对第一个式子求导带入 \(x=1\) 得
而将 \(x=1\) 带入二式化简可得
\(\mathcal O(Tm)\) 计算即可。
https://www.luogu.com.cn/record/46573608
20210215
ZROI1759 随机游走
题意
给定一棵根为 \(1\) 的有根树,定义 \(E_{S,T}\) 表示从 \(S\) 开始随机游走,到 \(T\) 停止的步数平方的期望,\(sub_u\) 表示 \(u\) 子树中所有点。
\(q\) 次询问,每次给定 \(u,v\) ,求 \(\sum _{x\in sub_u,y\in sub_v} E(x,y)\) ,保证 \(sub_u\cap sub_v=\varnothing\) 。
题解
定义 \(f_u\) 表示 \(u\rightarrow f_u\) 的概率生成函数。
先求一次的情况
带入 \(x=1\)
同理求二次
同理我们得到 \(g_u\) 表示 \(f_u\rightarrow u\) 的概率生成函数的一阶导和二阶导。
而对于 \(E_{u,v}\) 相当于将路径上每条边生成函数相乘的一阶导和二阶导之和,对多项式维护 \(f(1),f'(1),f’'(1)\) ,可以倍增维护。
而对于子树情况可以处理出每个点到 \(u/v\) 的生成函数,和上述同理。
时间复杂度 \(\mathcal O(q\log n)\) 。
http://zhengruioi.com/submission/310207
CF1252D Find String in a Grid *
题意
现有一个由大写字母构成的 \(n\) 行 \(m\) 列矩阵。
定义一个L型路径为,从矩阵某个位置开始,先向右走若干步,再向下走若干步,且不离开矩阵边界的路径。
定义一个L型字符串为对应的L型路径上字符依次连接起来组成的字符串。
现给定 \(q\) 次询问,每次给一个大写字母组成的字符串 \(S\) ,询问矩阵中包含多少个等于 \(S\) 的 L型字符串。
\(n\le 500, m\le 500, q\le 2\times 10^5\),所有查询的字符串长度之和\(\le 2\times 10^5\)。
题解
考虑暴力枚举转移点,那么问题为求出多少个位置使得该串与 \(T\) 的 \(lcp=T\) 。则对行与列分别建 \(SA\) ,那么可以快速查出点是 \(T\) 的位置。
则问题转化成给定一个长度为 $n\times m $ 的序列,每个位置有 \(A_i,B_i\) ,\(q\) 次询问,每次有 \(l_1,r_1,l_2,r_2\) ,求有多少 \(i\) 使得 \(l_1\leq A_i\leq r_1,l_2\leq B_i\leq r2\) 。
那么离线下来差分树状数组维护。
时间复杂度 \(\mathcal O(q\log n+n^2\log n)\) 。
update:
貌似有好写且能过的 \(\mathcal O(n^3)\) 的做法。
考虑枚举行,枚举转移点,用 \(AC\) 自动机匹配,那么我们去匹配转移点所在列。
那么我们得到的方案为 \(l\) 在转移点前 \(r\) 在转移点后或 \(l\) 在转移点后且 \(r\) 在转移点后。
由于 \(l\) 在转移点后且 \(r\) 在转移点后我们可能计算多次就仅在第一行计算。
20210216
最近点对问题 *
题意
给定平面上 \(n\) 个点,求其最近点对的距离。\(n\leq 10^5\) 。
题解
将点按照 \(x\) 从小到大排序,考虑分治处理。设 \(f(l,r)\) 表示点在 \([l,r]\) 中的最短距离,考虑求 \(f(l,r)\) 的值。
假设 \(d1=f(l,mid),d2=f(mid+1,r),d=\min\{d1,d2\}\) ,分割点的横坐标记为 \(x\) 。
那么我们只要记录横坐标在 \([x-d,x+d]\) 的点,因为其他点到分割线的距离就已经大于 \(d\) 了。
毛估估一下,对于一个点 \(x\) ,\(\leq d\) 的点数不多。事实上可以证明左右两侧均不超过 \(6\) 个,即在一个 \(d\times 2d\) 的长方形内不超过 \(6\) 个点 。
假设超过 \(6\) 个,我们将举行分成 \(6\) 个 \(\dfrac{1}{2}\cdot \dfrac{2}{3}\) 个小矩形,那么一定存在一个矩形内有两个点,但是一个矩形内最长点对为对角线 \(\dfrac{5}{6}d<d\) ,矛盾,故不存在。
那么只要按照 \(y\) 排序,找到在 \([y-d,y+d]\) 其中的点。
由于对 \(y\) 排序可以归并,故时间复杂度为 \(\mathcal O(n\log n)\) 。
BZOJ3636 教义问答手册 *
题意
一个整数序列,给定若干询问,每个询问形如:在 \([l_i,r_i]\) 中选若干个⻓度为 \(L\) 的不相交的区间,使得其和最大。
\(N=100000,Q=100000,L\leq 50\) 。
题解
分治询问,考虑跨过 \(mid\) 的询问,预处理出 \(suf_{l,x}\) 与 \(pre_{r,x}\) 分别表示在 \([l,mid]\) 中 \([mid-x+1,x]\) 被选择的最大值,以及在 \((mid,r]\) 中 \((mid,mid+x]\) 被选择的最大值。
答案即为 \(\max suf_{l,x}+pre_{r,x}\) 。时间复杂度 \(\mathcal O(\mathcal nL\log n+qL)\) 。
CF1100F Ivan and Burgers *
题意
给定一个长度为 \(n\) 的序列 \(a\) ,\(q\) 次询问,每次询问 \(a_l,…,r_r\) 中异或和的最大值。
\(1\leq n,q\leq 5\times 10^5\) 。
题解
将 多校省选 松鼠串门 放序列上,离线,每次维护最左元素。时间复杂度 \(\mathcal O(n\log c)\) 。
比赛 *
题意
有 \(n\) 个两两不相同的数 \(a_i\) ,现在你要选一些下标 \(i_1,i_2… i_k\),使得其 \(a\) 值单调不递减。然后对于一段极⻓的⻓度为 \(x\) 的空格,费用为 $ (x+1)^2$ 。求最小的费用。
\(1\leq n\leq 5\times 10^5\) 。
题解
设 \(f_i\) 表示考虑到 \(i\) 的最小费用,则。
显然可以斜率优化,但是 \(a_j<a_i\) 的条件比较难处理,则对于 \(a\) 排序,那么我们只要 \(j<i\) 即可。
那么通过类似 \(cdq\) 的方法更新,每次左区间加入凸包,右面计算。
时间复杂度 \(\mathcal O(n\log n)\) 。
AGC002D Stamp Rally *
题意
一张连通图,\(q\) 次询问从两个点 \(x\) 和 \(y\) 出发,希望经过的点(不重复)数量等于 \(z\) ,经过的边最大编号最小是多少。
\(n,m,q\leq 10^5\)。
题解
可以 \(kruskal\) 重构树加二分答案,时间复杂度 \(O(\mathcal n\log^2 n)\) 。
或者整体二分,定义函数 \(f(l,r,ql,qr)\) 表示当前并查集内已经合并边权在 \([1,l)\) 中,且询问在 \([ql,qr]\) ,维护一个可撤销并查集即可,时间复杂度 \(\mathcal O(n\log n)\) 。
LOJ6198 谢特 *
题意
给定一个长度为 \(n\) 的字符串 \(S\) ,且每个后缀有个 \(w_i\) ,求 \(\max LCP(i,j)+(w_i\mathbin{\text{xor}} w_j)\) 。
\(n\leq 10^5,w_i\leq n\)。
题解
先求 \(SA\) ,那么问题转化成求 \(\max_{i,j} \{\min_{k=i}^{j-1} h_k+(w_i\mathbin{\text{xor}}w_j\}\) 。
显然最小值分治,那么问题为两个子树选择两个点的异或值最大,正着做可以主席树维护可持久 \(Trie\),每次维护长度较小的那边。
或者将笛卡尔树建出来,那么从后往前就只要写个 \(Trie\) 合并即可,本质是笛卡尔树合并。
时间复杂度 \(\mathcal O(n\log n\log c)\) 。
gym101623F Factor-free tree *
题意
给出某一颗带点权树的中序遍历序列,问是否存在一颗对应的带点权树满足条件:每个节点的子孙节点的权值都和该节点的权值互质。如果存在则输出符合条件的树的每个节点父亲节点。
题解
考虑这样一种构造,我们找到一个数使得该数与其他数互质,然后将其为根递归左右。
可以发现这样做一定能在有解上可以找到一组解,因为若最后方案上不为根,可以 \(rotate\) 上去。那么可以将其看成最小值分治,故每次从两侧往中间一次判断保证时间复杂度。
那么我们只要查询一个点是否在一个区间内没有任何其他不互质的点,预处理 \(l_i,r_i\) 表示离它最近的 \(l,r\) 与它不互质。
那么判断 \(x\) 成立的条件是 \([l<x]\and [x<r]\) 。时间复杂度 \(\mathcal O(n\log n)\) 。
WC2010 重建计划 *
题意
给定一棵 \(n\) 个结点的树,含边权,给定 \(L,R\) ,求一条最大的简单路径其边数在 \(L\sim R\) 之间,且平均数最大。
题解
分数规划二分答案,那么问题转化成是否存在边数在 \(L\sim R\) 之间,且边权和 \(\geq 0\) 的简单路径。
点分治,考虑当前重心 \(x\) ,判断当前子树内的点与前面子树内是否存在一条简单路径,那么我们递归子树处理出每个深度的最大边权。
则问题转化成给定两个数组 \(A,B\) ,求是否存在 \(i,j\) 满足 \(L\leq i+j\leq R,A_i+B_j\geq 0\) 。单调队列优化即可,注意要处理前缀 \(\max\) 。
时间复杂度 \(\mathcal O(n\log^2 n)\) 。
20210217
TC11351 TheCowDivOne
题意
从 \(0\sim n-1\) 这些正整数里选出恰好 \(k\) 个互不相同的数,使得它们的和是 \(n\) 的倍数。求方案数。
\(k\leq 1000,n\leq 1e9\)
题解
将其答案按二元生成函数写出
设 \(f(x)=[y^k]\prod (1+x^j y)\) ,则
根据单位根反演可得
简称,多项式特定倍数的系数和为单位根点值和的 \(\dfrac{1}{n}\) 。
带入可得
而观察 \(\prod_{j=0}^{n-1} (1+\omega_{n}^{ij}y)\) ,令 \(\gcd (n,i)=d\) ,由于 \(\frac{n}{d},\frac{i}{d}\) 构成完全剩余系,即具有长度为 \(\frac{n}{d}\) 的循环节 。
则
观察后面的东西,为一个类似
由于
可以因式分解得到。
故
显然分 \(t\) 奇偶讨论可得
带入原式可得
由于 \(k\leq 10^3\) ,暴力计算即可,时间复杂度 \(\mathcal O(k^2)\) 。
https://www.luogu.com.cn/paste/c49pesqf
糖果 *
题意
有 \(n\) 个人和 \(m\) 种糖果,每种糖果分别有 \(a_i\) 个,每个人每种糖果至多吃一个,最多吃 \(b_i\) 种糖果。
有 \(q\) 次修改,每次可以把某个 \(a_i\) 或者 \(b_i\) 加 \(1\) 或减 \(1\),每次修改后问是否存在一种方案使得糖果可以被分完。
\(1\leq n,m,a_i,b_i\leq 3\cdot 10^5\) 。
题解
考虑如何判断有解,考虑网络流。(贪心无法显式的表达)
则连边很显然,设超级源以及超级汇,并且建立 \(n+m\) 个点, \(s\) 连向左侧 \(n\) 个点流量 \(a_i\) ,右侧到 \(t\) 连流量为 \(b_i\) ,中间全 \(1\) 。
最大流为 \(\sum a_i\) 即为合法,但是如何快速求解网络流。
注意到中间均有边,为满二分图,可以快速计算。考虑最小割,那么我们定义 \(S\) 表示与 \(s\) 相连的边, \(T\) 表示与 \(t\) 相连的边。
则最小割可以写成
考虑枚举 \(|S|\) ,那么显然 \(S\) 是取最大的 \(|S|\) 个 \(a\) ,而 \(b\) 的选取可以看成
那么维护 \(|S|\) 的线段树,注意到由于操作每次 \(+1/-1\) ,那么序列的大小关系是不会改变的。
则对于 \(a_i\) 的操作可以看成前缀加减,对于 \(b_i\) 的操作撤销重新计算。
即维护一个区间加,查询全局最小值的线段树即可。
时间复杂度 \(\mathcal O(n\log n)\) 。
JS集训 卖弱 *
题意
求有多少 \(n\) 个点 \(n\) 条边的有向图,每个点的入度出度都是 \(1\) ,并且如果 \(i\) 到 \(j\) 有一条边,必须要满足 \(j\) 在 \([i-a+1,i+n-a-1]\) 中。
\(n\leq 10^6,a<=200\) ,总共 \(10\) 组询问。
题解
将题意转化为给定一个 \(n\cdot n\) 的网格图,挖掉左上角边长为 \(a\) 的等腰直角三角形以及右下角边长为 \(n-a\) 的等腰直角三角形内选择 \(n\) 个点,其中横坐标互不相同,纵坐标也互不相同的方案数。
先考虑一个子问题,若仅挖去边长为 \(n-a\) 的三角形方案数是什么。从第一行开始递推,可得 \(a^{n-a}\cdot a!\) ,那么若挖去边长为 \(a\) 的三角形考虑容斥该三角形内部点的个数。
设 \(f_i\) 表示在边长为 \(a\) 的直角三角形内部选择 \(i\) 个点的方案数。
答案即为
时间复杂度 \(\mathcal O(Ta+a^2+n)\) 。
JS集训 硬币游戏*
题意
有 \(n\) 堆硬币,每堆恰好有三个硬币,从上到下价值分别为 \(a_i,b_i,a_i\) (即第一个和第三个价值相同)。拿走一个硬币必须先拿走它上面所有硬币。
对于每个 \(1\leq k\leq 3n\) ,求出恰好拿走 \(k\) 个硬币获得的最大价值。
\(n\leq 10^7\) 。
题解
诈骗题。对于每种硬币,把它拆成 \(a_i,a_i+b_i\) ,其中前者需要 \(1\) 的代价,后者需要 \(2\) 的代价。
于是就变为对于每个 \(k\) 求出代价总和为 \(k\) 的最大价值。
按照性价比贪心,对于每个 \(k\) ,若一个前缀恰好代价为 \(k\) 那么选它一定最优,否则调整一下最大的 \(1/2\) 。
时间复杂度 \(\mathcal O(n\log n)\) 。
JS集训 担心 *
题意
有 \(n\) 个人来参加比赛,每个人有属性 \(a_i\) 。每次等概率选择相邻两个进行单挑。若比赛双方选手为 \(u,v\) ,则 \(u\) 有 \(\dfrac{a_u}{a_u+a_v}\) 的概率获胜,\(v\) 有 \(\dfrac{a_v}{a_u+a_v}\) 的概率获胜。
求第 \(r\) 个人获胜的概率。
\(1\leq r\leq n\leq 500\) 。
题解
暴力 \(dp\) 设 \(f_{i,j,k}\) 表示合并完 \([i,j]\) ,其中 \(k\) 获胜的概率。暴力实现时间复杂度 \(\mathcal O(n^5)\) 。
但是由于我们可以通过 $k $ 必胜划分成在 \([i,k],[k,j]\) 中均为必胜的,且两个均独立。那么 \(f_{i,j,k}=f_{i,k,k}\cdot f_{k,j,r}\) 。
则我们只要记录 \(L_{i,j},R_{i,j}\) 表示在 \([i,j]\) 中,最后胜的为 \(i/j\) 的概率。
则
后面的可以在 \(dp\) 时算一下,故时间复杂度 \(\mathcal O(n^3)\) 。
零一树 *
题意
给定一棵长度为 \(n\) 的树,树上每条边都有边权,可以是 \(0\) 或 \(1\) ,现在有 \(m\) 对 \((u_i,v_i)\)。
定义一条路径长度 \(p_i\) 为 \(u_i\) 至 \(v_i\) 简单路径上边权和 \(\bmod 2\) 。问有多少种边权值方案使得 \(p_i\) 序列满足非递减。
\(1\leq n,m\leq 10^5\) 。
题解
若暴力枚举 \(0/1\) 分界点,那么问题转化为两点相同或不同,其中每个点均为 \(0\) 或 \(1\) 。
考虑并查集维护联通块,那么答案可以写成 \(2^{\frac{c}{2}-1}\),其中 \(c\) 表示联通块个数。
改为线段树分治维护即可,同时可撤销并查集维护联通块。
时间复杂度 \(\mathcal O(n\log^2n)\) 。
20210218
HAOI2018 染色 *
题意
\(n\) 个位置,\(m\) 种颜色,给定正整数 \(s\) ,对于每个 \(0\leq k\leq m\) 求出恰有 \(k\) 种颜色恰好出现 \(s\) 次的方案数。
\(n\leq 10^6,m\leq 10^5,s\leq 150\) 。
题解
看到“恰好"想二次项反演,那么设 \(f(i)\) 表示钦定 \(i\) 个其他任选的方案数,\(F(i)\) 表示恰好的答案。
那么
则
理性分析一下 \(i\) 的值域为 \([k,m]\) ,则做个 \(NTT\) 即可。
时间复杂度 \(\mathcal O(n\log n)\) 。
20210219
ZROI1775 令牌生成
题意
为了保障用户账号的安全,许多平台都需要用户在登录的时候输入绑定手机上的令牌,下面是 \(COAT\) 交友平台生成令牌的方式。
令 \(F(Q)\) 表示小于等于 \(Q\) 的数中可以表示成 \(2^x-2^y\) 形式的正整数的个数,其中 \(x,y\) 是非负整数。
考虑所有 \(F(Q)=N\) 的数 \(Q\) , 并将它们按照二进制表示中 \(1\) 的个数排序,如果有 \(1\) 数量相等的按照原数大小作为第二关键字。
在排好序的序列中选取第 \(K\) 个数对 \(998244353\) 取模的结果作为令牌,如果序列的长度小于 $ K$ , 输出 \(-1\) 表示获取令牌失败。
由于 \(COAT\) 的用户数量巨大,所以你需要设计一种高效的算法在短时间内回答多次查询。
\(1\leq N,K\leq 10^{18},1\leq T\leq 10^5\) 。
题解
题意感觉很乱,看起来像两问题拼在一起。
显然可以被表示成 \(2^x-2^y\) 的数为在二进制下仅有一个 \(1\) 的连续段。
那么 \(F(Q)=N\) 对应的区间连续且若表示成 \(1111…1000.000\) ,那么下一次 \(1\) 的个数会往后移动一个。
则问题变为了给定一个形如 \(2^x-1\) 的数,\(x\) 有可能很大,问在 \([0,2^x-1]\) 中在按 \(1\) 的个数排序后第 \(K\) 个数值。
注意到 \(1\leq K\leq 10^{18}\) ,毛估估一下位数不是很大,那么暴力算组合数计算。
则问题就变成如何比较组合数与某个数的值,注意到值不会很大,开 \(\text{int128}\) 暴力递推计算。
时间复杂度 \(\mathcal O(能过)\) 。细节较多~
http://zhengruioi.com/submission/311045
ZROI1776 串
题意
给定 \(n\) 个字符串 \(s_i\) ,\(q\) 次询问,每次询问两个串 \(s_u,s_v\) 的最长公共子串。
\(1\leq n,N\leq 50000,1\leq q\leq 10^5\) 。
题解
方法一:\(SAM\)
\(SAM\) 求两个串的最长公共子串的时间复杂度为短串的长度。
考虑根号分治,若询问两个串有一个串长度小于 \(\sqrt{N}\) ,则时间复杂度为 \(\mathcal O(\sqrt{N})\) 。
否则,最多有 \(\sqrt{N}\) 个字符串,那么总时间复杂度为 \(\mathcal O(N\sqrt{N})\) 。
那么我们只要每次暴力求在将答案记忆化即可。
时间复杂度 \(\mathcal O(q\sqrt{N})\) 。
http://zhengruioi.com/submission/311258
方法二:\(SA\)
和上述方法一样,只要支持每次用短串时间处理即可。
我们考虑求 \(s_u,s_v\) 的答案,那么求出 \(ht\) 后答案即为 \(x\in s_u,y\in s_y,\max\{\min_{i=x}^{y-1}ht_i\}\) 。
可以发现,若 \(x\rightarrow y\) 交其他 \(s_u,s_v\) 那么肯定不优,则我们只要对于 \(x\) 找到最近的 \(y\) 即可。
离线扫描即可。时间复杂度 \(\mathcal O(q\sqrt{N})\) 。
20210220
CF1375E Inversion SwapSort
题意
给定一个长度为 \(n\) 的序列 \(a\),求 \(a\) 中的所有逆序对 \((i_1, j_1), (i_2, j_2), \cdots, (i_m, j_m)\) 的一个排列 \(p\), 使得依次交换 \((a_{i_{p_1}}, a_{j_{p_1}}), (a_{i_{p_2}}, a_{j_{p_2}}), \cdots, (a_{i_{p_m}}, a_{j_{p_m}})\) 后序列单调不降。
\(1 \le n \le 10^3\),\(1 \le a_i \le 10^9\)。
题解
前情提要 link
有一位好鸽鸽告诉我证法了!\(\text{orz jiangly}\) 。(但复杂度不太对。
方法一
大家普遍的写法。先考虑 \(a_i\) 为 \(n\) 排列的情况。
设 \(p=a^{-1}\) ,那么 \(p_i\) 表示在 \(a\) 中为 \(i\) 出现的位置。
可以发现 \(p\) 与 \(a\) 的逆序对是一一对应的,实质上是 \(a\) 的下标与 \(p\) 的元素构成双射。
证明也十分简单,若 \(p_i>p_j,i<j\) ,由于 \(a_{p_i}=i,a_{p_j}=j\) ,那么在 \(a\) 中 \((i,j)\) 构成了逆序对,同理可得无法构成逆序对。
那么 \(p\) 与 \(a\) 之间的关系构成了一个双射。
由于题意是对于 \(a\) 的下标交换,那么即为对 \(p\) 的元素交换,而当 \(a\) 为 \([1,2,...,n]\) 后 \(p\) 即为 \([1,2,3,...,n]\) 。
则对 \(p\) 进行冒泡变为 \([1,2,3...,n]\) 即可解决问题。
若 \(a_i\) 不为 \(n\) 的排列那么离散化一下,并且相同的钦定下标小的小即可。
复杂度 \(\mathcal O(n^2)\) 。
方法二
再次 \(\text{%jiangly}\) 。
前情提要的做法本质上和方法一类似,可以发现最后 \(id\) 相当于 \(a^{-1}\) 。
那么毛估估一下就可以得到其实就是方法一倒过来并且跑的还慢的做法。
事实上就是将方法一的做法倒过来,并且改成冒泡排序就一模一样啦。
时间复杂度 \(\mathcal O(n^3)\) ,别问为啥跑过去了。
NOI2018 你的名字
题意
给定字符串 \(S\) ,有 \(q\) 次询问。每次有字符串 \(T\) 以及 \(l,r\) ,问 \(T\) 中有多少个本质不同的串在 \(S[l:r]\) 中没有出现。
\(1\leq l\leq r\leq |S|\leq 5\times 10^5,\sum |T|\leq 5\times 10^5\) 。
题解
先考虑 \(l=1,r=|S|\) 的问题。
考虑 \(|T|\) 的前缀 \(T[1:i]\) ,它的后缀 \(T[j:i]\) 是 \(S\) 的子串,\(j\) 的求法和 ZROI1776 串 类似,即为 \(J_i\) 。
那么我们就要处理本质不同,考虑对 \(T\) 建 \(SAM\) ,答案即为
其中 \(min_i\) 表示任意 \(s\in endpos_i\),选取最小的即可,,\(J_i\) 表示上述的 \(j\) 。
式子也很显然,我们对于每个字符串对应到任意一个的 \(endpos\) 上。
而对于无 \(l,r\) 限制的仅对 \(S\) 维护 \(endpos\) 集合,拿线段树合并做,就可以维护 \(J\) 。
时间复杂度 \(\mathcal O(|S|\log |S|+26\sum |T|)\) 。
CF1037H Security *
题意
给定字符串 \(S\) ,共 \(q\) 次询问,每次给定字符串 \(T\) 以及 \(l,r\) 你需要找出字典序最小的字符串 \(S_1\) 满足 \(S_1>T\) 且 \(S1\) 是 \(S[l:r]\) 的子串。
\(1\leq |S|\leq 10^5,1\leq q\leq 2\times 10^5,\sum |T|\leq 2\times 10^5\) 。
题解
对于 \(S\) 建 \(SAM\) ,那么匹配就可以通过找 \(endpos\) 实现。
考虑 \(S[l:r]\) 与 \(T\) 的最长公共子串为 \(len\) 时,若存在出边那么直接拼一个 \(c\) 满足 \(c > T_{len+1}\) 即可。
否则去判断 \(len-1\) 是否存在解。
则用线段树合并维护 \(endpos\) 即可,时间复杂度 \(\mathcal O(|S|\log |S|+26\sum |T|)\) 。
HEOI2016/TJOI2016 字符串 *
题意
给定字符串 \(S\) ,\(q\) 次询问,每次给定 \(a,b,c,d\) ,求 \(S[a:b]\) 的所有子串与 \(S[c:d]\) 的最长前缀。
\(1\leq |S|,q\leq 10^5\) 。
题解
建 \(SA\) ,先二分答案,设答案为 \(o\) ,那么对于 \(c\) 所在的点我们只要判断是否存在 \(p\in [a,b-o+1] ,\min_p^c w\geq o\) 。
那么我们对于 \(c\) 找到左右最近的在 \([a,b-o+1]\) 的数判断即可。
可持久化线段树二分可以轻松实现。时间复杂度 \(\mathcal O(q\log^2 n)\) 。
\(SAM\) 可以先将 \(S\) 翻转,二分答案 \(o\) 。那么问题变为 \(S[c-o+1:c]\) 在 \(S[b:a]\) 中是否出现。
先线段树合并维护 \(endpos\) 集合,记录 \(S[1:c]\) 在 \(parent\) 树的结点,倍增跳到在 \(S[c-o+1:c]\) 的结点,那么仅要查一下 $endpos $ 即可。
时间复杂度 \(\mathcal O(q\log ^2n)\) 。
20210221
ZJOI2019 密码
题意
有 \(n\) 个开关,每个开关有属性 \(s_i\in\{0,1\}\) ,\(0\) 表示关,\(1\) 表示开,还有属性 \(p_i\) 表示有 \(\dfrac{p_i}{\sum p}\) 的概率将其 \(s_i\) 翻转。
问期望次数使得所有开关均 \(s_i=0\) 。
\(1\leq n\leq 100,1\leq \sum p\leq 5\times 10^4\) 。
题解
设 \(\sum_{i=1}^n p_i=P\)
由于开关有标号,用 \(EGF\&PGF\) 表示将 \(s_i\) 变为 \(0\) 的概率指数生成函数,设为 \(f_i(x)\) 。
则
设 \(f(x)=\prod_{i=1}^n f_i(x)\) ,则 \([x^k] f(x)\) 表示次数为 \(k\) 时满足 \(s_i\) 均为 \(0\) 的概率。
但是有可能在 \(k\) 前面就已经到达,那么设 \(g(x)\) 表示移动 \(k\) 次且保持原状态的概率。
但是咱们要求的是 \(OGF\&PGF\) 。
设 \(f(x)\) 的 \(OGF\) 为 \(F(x)\) ,\(g(x)\) 的 \(OGF\) 为 \(G(x)\) ,答案的 \(OGF\) 为 \(H(x)\) 。
如何将 \(EGF\rightarrow OGF\) ,以 \(f\) 为例,可以将函数写成
\(a_i,b_i\) 的求法可以暴力乘法背包得到。
则
由于 \(H(x)\) 为 \(PGF\) ,期望为 \(H’(1)\) 。
那么只要求 \(F’(1),F(1),G(1),G’(1)\) 即可。
但是观察 \(F,G\) 发现他们在 \(x=1\) 时是不收敛的,因为当 \(i=P\) 时分母会出问题。
但是答案一定是收敛的,那么我们将 \(F,G\) 均乘上 \((1-x)\) ,可以发现此时 \(F,G\) 收敛。
则
将 \(x=1\) 带入 \(H’(1)\) 即可解决。时间复杂度 \(\mathcal O(n\sum P+p\log mod)\) 。
20210222
GYM101234D Forest game *
题意
给定一棵 \(n\) 个结点的树,每次选择一个未被删除的结点删除,并将权值加上该点所在联通块大小。
求权值的期望。
\(1\leq n\leq 10^5\) 。
题解
设 \(f_{i,j}\) 表示 \((i,j)\) 点对计算答案,即在 \(i\) 点被删除时 \(j\) 在 \(i\) 联通块中。
则 \(E(x)=E(\sum f)=\sum E(f_{i,j})\) ,而 \(f_{i,j}=1\) 当且仅当 \(i\rightarrow j\) 的路径 \(i\) 是第一个被删除的。
那么 \(f_{i,j}=\frac{1}{dis_{i,j}+1}\) ,\(dis_{i,j}\) 表示 \(i\) 到 \(j\) 的距离。
则答案为 \(\sum_i\sum_j \frac{1}{dis_{i,j}+1}\) ,而 \(dis_{i,j}\) 的不同种类可以点分治加 \(NTT\) 求出。
时间复杂度 \(\mathcal O(n\log^2 n)\) 。
CF653F Paper task *
题意
给定一个长度为 \(n\) 的括号串 \(S\) ,问有多少个本质不同的合法括号子串。
\(1\leq n\leq 5\times 10^5\) 。
题解
看到本质不同先建 \(SAM\) ,那么我们只要知道当 \(l\in[L,R]\) 时有多少个 \(S[l:r]\) 是合法括号串。
考虑括号串的折线模型,由于处理的是后缀那么将 \((\) 看成 \(-1\) , \()\) 看成 \(1\) 。
那么对于一个串 \(S[l:r]\) 合法当且仅当 \(suf_l=suf_r,\min_{i=l}^r suf_{i}-suf_{r-1}=0\) 。
由于 \(r\) 确定那么极长 \(suf_i-suf_{r-1}\geq 0\) 可以二分 \(ST\) 表得到,而 \(suf_l=suf_r\) 记个桶维护即可。
时间复杂度 \(\mathcal O(26n+n\log n)\) 。
矩形覆盖 *
题意
给定一个大小为 \(n\cdot m\) 的矩形,某一些格子上有物品,共有 \(k\) 个物品,现在等概率选一个子矩形,求子矩形内物品个数的方差。
\(1\leq n,m\leq 10^9,1\leq k\leq 10^5\) 。
题解
由于 \(Var(x)=E(x^2)-E^2(x)\) ,那么仅要求 \(E(x),E(x^2)\) 。
\(E(x)\) 很好计算,\(E(x)=\sum_{i=1}^k x_i\cdot (n-x_i+1)\cdot y_i\cdot (m-y_i+1)\) 。
而 \(E(x^2)\) 等价于求点对贡献,若 \(i,j\) 均为 \(1\) ,那么扫描线一下即可。
时间复杂度 \(\mathcal O(k\log k)\) 。
20210223
Dice *
题意
一个 \(m\) 面的公平骰子,求最后 \(n\) 次结果相同就结束的期望次数或者求最后 \(n\) 次结果全不同就结束的期望次数。
\(n,m\leq 10^6\) 。
题解
第一问:
设 \(F(x)\) 表示答案的 \(PGF\) ,\(G(x)\) 表示还未结束的 \(PGF\) ,则
第二个式子表示枚举多了多少个能补。
解得
第二问:
设 \(F(x)\) 表示答案的 \(PGF\) ,\(G(x)\) 表示还未结束的 \(PGF\) ,同理可得
20210224
ZROI1782 二叉树
题意
有一棵无穷大的完全二叉树 \(T\),任意一个点都有两个子节点。
给定一棵有限的二叉树 \(G\),满足除叶节点外每个节点都有恰好两个儿子,你需要把 \(G\) “嵌入” \(T\) 中。具体的,你需要找一个单射 \(f:G\rightarrow T\),并且需要满足以下要求:
- 对于 \(G\) 中的每个非叶节点 \(u\),设其两个子节点分别为 \(l,r\),则 \(f(l)\) 在 \(f(u)\) 的左子树中,且 \(f(r)\) 在 \(f(u)\) 的右子树中。
- 对于 \(G\) 中的每个叶节点 \(v\),\(f(v)\) 的深度必须恰好为 \(h_v\),其中一个点的深度是它到根节点所需要经过的边数。\(h\) 是一个给定的数组。
你需要求方案数对 \(10^9+7\) 取模的结果。
\(1\leq n\leq 5000,0\leq h_i\leq 10^9\) 。
题解
先考虑一个 \(\mathcal O(nh)\) 的 \(dp\) ,设 \(f(i,j)\) 表示当 \(i\) 选取深度为 \(j\) 时子树的答案,\(T_i\) 表示 \(i\) 号点可以选取的最大深度,则
定义 $g(i,j)=\sum_{k=j+1}^{T_i} f(i,k)\cdot 2^k $ ,那么
答案即为 \(g(1,0)\) ,时间复杂度 \(\mathcal O(nh)\) 。
可以归纳证明 \(g(i,j)\) 一定形如
考虑归纳证明。
当 \(i\) 为叶子时,显然 \(a_{i,0}=2^{h_i}\) 。
若 \(i\) 不为叶子结点,假设他的左右儿子 \(l,r\) 均合法,那么
得证。
写个树背包维护 \(b\) 即两式的卷积,时间复杂度 \(\mathcal O(n^2)\) 。