省选前的做题记录(Round3)

[CF1131G] Most Dangerous Shark

用栈维护左侧不能被推倒的骨牌位置,求出每个骨牌向左推倒后的影响区间\(L_i\),右侧区间\(R_i\)求法类似。
那么只考虑最后一个骨牌的倒下方式,有:\(f_{i} = min\{f_{j-1(R_j \ge i)} + C_j , f_{L_i-1} + C_i\}\)
我们需要想办法\(O(1)\)实现第一个转移。
观察一下骨牌区间\([L_i,R_i]\)的性质,不难发现两个骨牌区间之间的关系只有包含和相离两种情况。
于是合法的右端点\(R_i\)从左往右是单调递减的。
维护一个\(f_{i-1} + C_i\)从顶到底单调递增的栈。对于\(R_i\)相同的若干位置,只保留最优位置。
每次转移时暴力弹栈,这样就保证了栈中时刻是从底往顶依次包含,且右端点\(R\)依次递减的区间。

[CF1129B] Wrong Answer

考虑这样构造:\(-1,a_1,a_2...a_t,0,0,...0,0\) ,设序列长度为\(L\)\(S = a - 1\)
它的程序跑出来的答案为\((L-1)S\),而我们设正确答案为\(L(S-1)\)
那么误差\(K = L(S - 1) - (L - 1)S = S - L = K\),把\(L+K\)\(a_1...a_t\)中分配一下即可。

[CF1129C] Morse Code

首先对\(01\)串建立后缀自动机。
对于后缀自动机上的每一个结点,它所代表的串之间为后缀关系。
所以对于后缀自动机的每一个结点,我们倒着把它所代表的串的答案全部\(dp\)出来,最后求和。

[CF1129D] Isolation

考虑维护区间内只出现一次的数的个数,最优的选择显然是分块。
但是分块面临的问题在于如何维护块内前缀和,直接块内二分复杂度会带\(log\)无法通过此题。
注意到在当前序列后面加入一个元素,影响的范围是一段区间,且每个点只会作为一个区间的端点。
所以对于一个长度为\(\sqrt{n}\)的区间,本质不同的取值也只有\(\sqrt{n}\)个,且值域连续。
所以对于每个块求出区间值域最大值和最小值后暴力重建,每个块内额外维护一个\(vector\)和指针\(pt\)来求答案。

[CF1129E] Legendary Tree

固定一个顶点为根,然后对于点\(u\),询问\((root,|V|-\{root,u\},u)\)得到每个点的子树大小。
然后考虑\(dfs\)求出这棵树。
根据一般套路,当我们在\(u\)时,我们肯定是要二分当前点集,设二分端点为\(p\),存问\((root,u,p)\)\(check\)
但是这样存在一个问题:二分到的点不一定会是\(u\)的直接儿子。
但是对于当前未确定的点,二分到的\(size\)最大的点一定会是直接儿子,所以实现把点按照\(size\)排序即可。

[LOJ6494]LJJ 的字符串

考虑枚举\(Endpos\)的距离之差\(len\),胡思乱想可以发现,我们可以类似[NOI]优秀的拆分来做。
我们把序列每隔\(len\)设置一个顶标\(p\),对于后面那个串\(endpos\in [p_i,p_{i+1})\)的二元组,它在\(p_i\)位置一定要匹配上。
所以枚举相邻两个顶标\(p_i,p_{i+1}\),求出它们的\(lcs,lcp\)
手推一下发现这是一个区间加上一段类似等差数列的和的贡献。
比较机智的做法是把贡献抽象为二次函数,对每一个系数差分。比较呆(比如我)的做法就是直接上四阶差分。

[BJOI2018]治疗之雨

典型的高斯消元。 对于\(K\)次攻击掉\(t\)滴血,概率\(p_t = \frac{\binom{K}{t} m^{K-t}}{(m+1)^t}\)
然后我们可以列出一个方程组,你可以发现它的系数矩阵(非0部分)长这样:
aa
aaa
.....
aaaaaaa (n个值)
aaaaaaa (n个值)
我们从下往上,每次只消上一行,一遍消元后就可以得到一个上三角。
然后再从上往下做高斯消元的第二部分。这样做就可以\(O(n^2)\)解出整个方程组了。

[BJOI2018]链上二次求和

转化为求长度\(\leq r\)的答案,我们设原数组为\(a_i\),设\(a_i\)的前缀和为\(s_i\)
那么\(Ans = \sum_{i=1}^r (\sum_{j = i}^n s_j - \sum_{j=0}^{n-i} s_j) = (\sum_{i=1}^r \sum_{j=i}^n s_j) - (\sum_{i=1}^r \sum_{j=0}^{n-i} s_j)\)
前面一部分 = \(\sum_{i=1}^r is_i + r\sum_{i=r+1}^n s_i\)
后面一部分 = \(r\sum_{i=1}^{n-r}s_i + n\sum_{i=n-r+1}^n s_i - \sum_{i=n-r+1}^n is_i\)
\(\sum_{i=seql}^{seqr} s_i\)显然是可以维护的,所以只用考虑维护\(g(r) = \sum_{i=1}^r is_i\)
\(g(r) = \sum_{i=1}^r \sum_{j=1}^i a_j = \sum_{j=1}^r a_j \sum_{i=j}^r i = \frac{r(r+1)}{2}\sum_{j=1}^r a_j - \sum_{j=1}^r \frac{j(j-1)}{2}a_j\)
用线段树维护\(\sum s_i\)\(\sum a_i\)\(\sum \frac{i(i-1)}{2}a_i\)的值即可。

[BJOI2018]双人猜数游戏

如果同时有了\(n\times m\)\(n + m\),就能够直接解出\(n,m\)
所以现在\(alice\)的目标为获得\(n + m\)的值,\(bob\)的目标为获得\(n\times m\)的值。
先考虑\(t=2\)。若\(bob\)先手,\(bob\)回答\(No\)\(alice\)能猜出来,则说明\(n\times m\)只有一种分解法。
同理,若\(alice\)回答\(No\)\(bob\)能够直接猜出来,则说明\(n = m = s\),即\(n+m\)只有一种分解法。
如果第一轮结束还未得解,则\(alice\)可以枚举\(n\times m\) 的拆分\(a \times b\),然后判断上一轮\(bob\)手上若为\(a+b\),则是否可以直接得解。
若可以,则\(alice\)可以直接排除掉\(a\times b\)这个组合。
对于\(n\times m\),若它的所有拆分方案经过排除后只剩下唯一一个,那么\(alice\)本轮就能够确定答案。
同理\(bob\)可以枚举\(n+m\)的所有拆分\(a+b\),假设\(alice\)手上为\(a\times b\)她上一论是否能够直接得解,若可以则排除\(a+b\)这个二元组。
对于\(n+ m\),若它的所有拆分方案经过排除后只剩下唯一一个,那么\(bob\)本轮就能够确定答案。
可以发现两人手上的决策都在不断减少。
\(f_{t,x,y}\)表示两人一共说了\(t\)\(No\)后,\(x,y\)这个二元组是否能够被当前决策者(非上一个说话者)猜出来。
转移直接模拟上面所说的思想。
最后对于\(f_{t-1,x,y}=0\)\(f_{t,x,y}=1\)的备选答案\((x,y)\),检查当前这个人说\(Yes\)后另一个人是否也能说\(Yes\)即可。

[TJOI2018]游园会

典型的\(DP\)\(DP\)
\(LCS\)的转移:\(f_{i,j} = f_{i-1,j} , f_{i,{j}} = min(f_{i,j-1},f_{i-1,j-1}+[{s_i==t_j}])\)
所以\(f_{i,j} \leq f_{i,j+1} \leq f_{i,j} + 1\)
\(f_{i,j+1} - f_{i,j}\)的取值全部状压起来,预处理转移系数然后暴力转移。

[Wannafly9E] 组一组(口胡)

分位考虑,把区间和转为前缀相减,然后差分约数。 注意对于前缀和,有\(s_i \leq s_{i+1} \leq s_[\)

[CF819C] Envy(口胡)

对于最小生成树:同边权的边加入条数不变,加入后的连通性不变。
按照权值分层,预处理每一种边权的边连接的联通块编号,每次\(check\)加入该边权的边后是否有环。

[ATCoder3611] Tree MST(口胡)

根据\(Krsukal\),加入\((s+1,t+1,c+2)\)时,\((s,t,c),(s,t+1,c+1)\)已经在同一联通块了。
所以我们可以等价的把\((s+1,t+1,c+2)\)变为\((s,s+1,c+2)\)
这样原来稀奇古怪的边就变成了一个环状结构,我们扫两边求出环上边的最小值,再与\((s,t,c)\)的边做最小生成树。

[Atcoder2134] Zigzag MST(口胡)

首先点分治去掉\(w(u)\),\(w(v)\)的点权条件,此时我们只需要考虑\(dis(u,v)\)
我们找到当前点分子树中\(dis(root,u)\)最小的\(u\),考虑从它开始构建最小生成树。
设它已经与点集\(V_1\)联通,那么\(V_2\)的点与\(V_1\)的点联通的最佳方式都为\(dis(u,root) + dis(v\in V_2,root)\)
所以在设当前点分子树的点集为\(V\),我们只需要保留\((u,v\in V)\)这些边即可。最后用保留的边做最小生成树得解。

[BZOJ4331] 越狱老虎桥(口胡)

可以注意到强联通分量里的边不能删,所以先缩点,然后考虑一棵树。
若我们选择的点集在树上不存在分叉,则可以用一条链覆盖。 所以二分答案后树形\(dp\)进行\(check\)

[BZOJ4061] Farm and factory

设原来的点为\(u\),新加的点为\(p\),设\(d(a,b)\)表示\(a\)\(b\)的最短路。
我们强制\(d(p,1)\)为我们新加的一条边的长度,即\(d(p,u) + d(u,1) \ge d(p,1)\)
根据题意我们有:\(d(u,p) + d(p,1) \ge d(u,1)\)
所以\(d(u,p) \ge |d(u,1) - d(p,1)|\),同理\(d(u,p) \ge |d(u,2)-d(p,2)|\)
所以\(d(u,p) = max\{|d(u,1) - d(p,1)| , |d(u,2)-d(p,2)|\}\)
我们把\((d(u,1),d(u,2))\)看成坐标系上的若干点,那么我们的问题就是找一个点使得它到其他点的切比雪夫距离之和最小。
做法:转为曼哈顿距离后两维分开取中位数。

[Codechef] Querying on a Grid(口胡)

考虑分治,对于当前区间中点\(mid\),我们分别处理三个元素到当前区间的最短路径树。
对于修改操作,我们递归查询最短路在哪个最短路径树上。
设在\(p\)位置的最短路径树上,那么我们所需要做的就是树上路径加法,差分后直接用\(BIT\)维护。

[LOJ6036] 编码

先考虑暴力\(2-sat\),建两排点\((s_{i,0},s_{i,1})\)表示选\(0/1\),然后\(O(n^2)\)枚举后连边。
优化显然是要用\(Trie\),关键在于怎么连边,我们把串在\(Trie\)上走,到了\(?\)就分叉,最后一个串为走到两个位置。
以走到了填\(0\)所在的位置\(p\)为例。
先考虑正命题:若当前位置填\(0\),则前缀上的所有串都要填异与该链的元素。
直接想法是\(p \to fa_p , s_{i,0} \to p, p\to s_{i,1}\),然而把填\(1\)那一端的连边也画出来就会发现形成了一个自环。
这个问题其实相当好解决,我们把连边变为前缀连边,这样\(s_{i,0}\)就不会连到\(s_{i,1}\)了。
具体来说:\(p' = NewNode() , p \to fa_p , p' \to p,s_{i,0} \to p , p' \to s_{i,1}\)
逆命题:若上面填了该链元素,则当前点不能填\(0\)
连边并没有什么区别:\(p' = NewNode,fa_p\to p,p\to p',s_{i,0}\to p',p \to s_{i,1}\)
连完边后跑\(Tarjan\)求答案。

[CF429E] Points and Segments

一个套路题,考虑序列欧拉回路存在的充要条件,然后直接跑欧拉回路求解。

[BZOJ4886] 叠塔游戏

可以发现一个合法方案中,一个底最多出现两次。而对于一个矩形,我们是在二元组中二选一。
不难想到基环森林。
把初始答案设为\(\sum (A+B)\),用并查集维护,对于树保留联通块最大值,对于基环树则把整个联通块删掉。

[IOI2016] RailRoad

题目可以抽象为:通过加一些有向边,使得原图存在从\(1\)出发的欧拉路径。
我们先加一条\((1,inf)\)的边,因为从小往大连的边不需要代价,所以最终方案一定为:\(1\to end\to inf\)
所以我们就可以直接考虑构造合法欧拉回路了。
考虑序列欧拉回路存在的充要条件:每一段左右覆盖次数相同、图联通。
我们通过差分就可以知道每一段需要的额外覆盖数,对于每一段,我们直接用\(|Init|\)条对应边覆盖。
因为不跨段连边显然对连通性的保证更优。
连完后图有可能依旧不联通,我们依旧用不跨段边跑一个最小生成树即可。

[BZOJ4423] Bytehattan(口胡)

平面图转对偶图,把网格外部算作一个大点,那么平面图不联通等价与对偶图成环,并查集维护。

[Wannafly4F] 线路规划

套路题,连续段对应连边考虑考虑使用倍增并查集\(dsu[e][u]\)
使用\(Kruskal\)算法,把边按照边权从小到大排序。
每次连边时暴力递归,若当前区间并查集已联通则\(return\),否则暴力递归,当到达\(e = 0\)时合并两个联通块信息。
因为总共只有\(O(nlogn)\)个并查集,每个并查集只会被遍历一次,所以复杂度均摊下来就是\(O(n\alpha logn)\)

[BJOI2018]染色

如果图存在奇环,那么连二分图都不是可以直接卡掉。
下面我们只考虑一个联通块的情况,因为全局答案就是每一个联通块的答案与起来。

  • 技巧1:对于一条长度为\(len\)的链,如果这条链上的集合全部一样,它等价与一个长度为\(len\%2\)的链。
  • 技巧2:考虑一个四元环\((a,b,c,d)\),我们可以使用集合\((AB,AB,BC,AC)\)来使得\(a=B\),\(b=A\)固定。

那么假设联通块内存在两个环,它们的边不相交。
任取一条链使得两个环连接(类似一个手铐形状),我们把其他边直接删掉,用技巧1直接把它们的距离拉近。
对于一个环,我们用技巧\(2\)固定链的一个端点,那么传递到链的另一端,我们固定了另一个环的一个端点。
设这个端点为\(a\)且被固定为\(A\),则我们使用:\((b=\{AB\},c=\{BC\},d=\{AC\})\)就能卡掉。
我们还剩下两种情况:三个环两两有交、一个横着的\(8\)字形。
对于横着的\(8\)字形,我们把最短的一条边拖到中间,以两个度数为\(3\)的点为端点,用\((a,b,c)\)描述这个图。
其中\(a,b,c\)为从左往右三条路径的长度。
不难发现,对于一个三个环两两有交的图,它至少包含一个规模为\((3,1,3)\)\(8\)字形,我们后面会证明这种\(8\)字形不合法。
考虑哪些\(8\)字形合法。
对于\((2,2,2)\)可以发现它一定合法。
对于\((3,1,3)\),卡掉方式为\((\{AC,BC\}\{AB,AB\} \{BC,AC\})\)
对于\((4,2,4)\),卡掉方式为\((\{AC,BC,AB\}\{AB,AB,AB\},\{BC,AC,AB\})\)
对于更大的\(8\)字形,均可以使用技巧\(2\)缩成\((3,1,3)\)或者\((4,2,4)\),即都能够被卡掉。
综上所属,合法的方案只有树或者一个环或者\((2,even,2)\)\(8\)字形,大力判一下直接输出即可。

[ZJOI2017]字符串

首先要知道策仙的字符串理论:
对于一个子串\(S\),设后缀\(s\)为好的当且仅当存在一个\(t\)使得\(st\)\(St\)的最小后缀。
结论:好的后缀\(s\)的个数不超过\(log_2 |S|\)个。
证明:
反证,设两个好的后缀\(a,b(|b|<|a|)\)满足\(|b| > \lfloor \frac{|a|}{2} \rfloor\)
\(a\)\(b\)都要能够成为好的后缀,则\(b\)一定要是\(a\)的一个前缀(在\(|b|\)长度内比不出大小),即\(b\)\(a\)\(Border\)
由于\(a\)长度大于\(b\)的一半,所以\(a\)存在一个周期\(T = b - a\),设\(a = TTc, b = Tc\),其中\(c\)\(a,b\)的一个前缀。
不妨设\(T = cw\),则\(a = cwcwc\)\(b = cwc\),故\(at = cwcwct\)\(bt = cwct\)
由于\(cwct\)能够成为最小后缀,故\(cwct < ct\),即\(w < t\)
\(w < t\),所以\(cwcwct < cwct\),所以\(a < b\)恒成立,即\(b\)不可能成为好的后缀,矛盾。
\(|b| \ge \lfloor \frac{|a|}{2} \rfloor\)恒成立,即一个串\(S\)好的后缀\(s\)的个数不会超过\(log_2|S|\)

然后考虑用线段树暴力维护,线段树每个点开\(vector\)保存所有好的后缀。
设左儿子的串为\(u\),右儿子的串为\(v\)
由于线段树左右区间满足\(|u| \leq |v| \leq |u| + 1\),所以\(lson\)最多只会保留一个好的后缀。
暴力\(for\)左儿子中两个相邻的好的后缀然后比大小来进行合并。
若不同则保留字典序小的,否则保留长度较长的(原因见证明),这样复杂度依旧没有问题。
唯一的问题在于\(O(1)\)\(lcp\)了。
观察到\(m\)的范围比较小,所以分块维护\(Hash\)就可以做到\(O(\sqrt{n} \sim 1)求\)lcp$$。

[LOJ6146]Normal

\(A\)为转移矩阵,则:\(Ans = \sum_{i=0}^{T}[x|i] \binom{T}{i} A^i\),其中\(Ans\)也为一个矩阵。
看到\(K=2,4,7,8\),出题人帮你设计的明明白白所以大力单位根反演:\(Ans = \sum_{i=0}^T(\sum_{j=0}^{x-1} w_{x}^{ij})\binom{T}{i} A^i\)
交换求和号后:\(Ans = \sum_{j=0}^{x-1} \sum_{i=0}^T \binom{T}{i}(w_{x}^j)^iA^i = \sum_{j=0}^{x-1} (1 + w_x^jA)^T\)
可以注意到\(A\)是一个循环矩阵,所以可以考虑使用循环卷积来代替循环矩阵。
这样我们要做的就是循环卷积了。
观察这个卷积,一共\(n-1\)项,\(x\)的指数对\(n\)取模,这是单位根的经典应用了,带入\(n\)次单位根大力\(dft\)即可。

[LuoguU28854]pfs

\(min-25\)筛,预先处理质数个数,筛第二部分的时候传参递归计算。

[LOJ6300]博弈论与概率统计

把问题抽象为:从\((0,0)\)出发,赢一局向右走一步,输一局向上走一步,最终走到\((n,m)\)
我们以\(n\ge m\)为例。
答案的范围为\([n-m,n]\),我们来探究一下什么情况下答案会为\(n-m+t\)
手玩一下不难发现是:行走路径碰到了\(y=x+t\)但没有碰到\(y=x+t+1\)
这是卡特兰数的经典问题了,答案即\(\binom{n+m}{n+i} - \binom{n+m}{n+i+1}\)
所以\(Ans = \sum_{t=0}^m [\binom{n+m}{n+t} - \binom{n+m}{n+t+1}] = (n-m)\binom{n+m}{n} + \sum_{i=0}^{m-1} \binom{n+m}{i}\)
类似的,当\(n < m\)可以发现:\(Ans= \sum_{i=0}^{n-1} \binom{n+m}{i}\)
我们可以知道:\(\sum_{i=0}^{n-1} \binom{n+m}{i} + \sum_{i=0}^{m-1} \binom{n+m}{i} = 2^{n+m} - \binom{n+m}{n}\)
所以我们的问题变为动态维护:\(F(n,m) = \sum_{i=0}^{m-1} \binom{n+m}{i}\)
一个非常神奇的做法,考虑移动端点:
\(F(n,m+1) = \sum_{i=0}^m \binom{n+m+1}{i} = \sum_{i=0}^m \binom{n+m}{i} + \binom{n+m}{i - 1} = 2F(n,m) + \binom{n+m}{m}\)
类似的可以推得:
\(F(n+1,m) = 2F(n,m) - \binom{n+m}{m-1}\)
\(F(n,m-1) = \frac{1}{2} (F(n,m) - \binom{n + m - 1}{m - 1})\)\(F(n-1,m) = \frac{1}{2}(F(n,m) + \binom{n+m-1}{m-1})\)
所以离线后直接用莫队维护即可。

猜你喜欢

转载自www.cnblogs.com/GuessYCB/p/10465054.html