- 博客(21)
- 收藏
- 关注
原创 树状数组(BIT)/Fenwick树维护和查询前缀信息
先说查询,要查询区间[1,x],首先查B[x]得到[x-lowbit(x)+1,x]的信息,然后执行y=x-lowbit(x),得到[y-lowbit(y)+1,x-lowbit(x)]的信息,一直执行减去lowbit的操作直到x归零再将所有区间合并,即可不重不漏地获得[1,x]区间。假设y所代表的区间[y-lowbit(y)+1,y]包含x,那么意味着y-lowbit(y)<=x且y>=x。在BIT中,B[x]维护的区间是[x-lowbit(x)+1,x]。
2025-03-24 20:01:16
142
原创 LCA问题转化为±1RMQ问题
由于从节点u走到节点v的过程中必然经过LCA(u,v)且不会经过LCA(u,v)的父节点,所以节点u、v的LCA就是欧拉序列区间[pos[u], pos[v]]中最小节点(假设为w)所对应的D[w]。这里把分块长度改为logn/2,所以可以把每个块转化为logn/2-1长度的二进制序列,对于转化后的二进制序列不同的块称为本质不同的块,而本质相同的块查询结果是相同的。本质不同的块的数量为2^(logn/2),暴力处理所有本质不同的块的所有可能查询复杂度为(2^(logn/2))^2=2^(logn)=n。
2025-01-23 14:44:53
180
原创 Codeforces 54D Writing a Song
假如i为某空位置,那么pos[i]必为0。假设从i位置往后x个位置为第一个不为p[0],从j位置往后y个位置第一个不为p[0],那么必有x>y(i和j中间pos为0的位置都填入了p[0]),因此必有ans[i:i+len(p)-1]≠p,。最后往空的位置填字符,如果p由单种字母组成即p的周期为1,这种比较简单直接填不是p[0]的字母就行。给定字符串p和一个pos数组,输出一个只使用前k个字母的n长度字符串,要求在pos[i]==1的位置匹配p,在pos[i]==0的位置不匹配。
2024-12-10 22:56:48
120
原创 后缀树(Suffix Tree)简介
新建一个z,使st[z]=n,len[z]=inf,再新建一个u,使st[u]=st[v],len[u]=rem-1,tran[now][S[n-rem+1]]=u,tran[u][S[st[v]+rem-1]]=v,tran[u][c]=z。首先如果len[tran[now][S[n-rem+1]]]>rem,就跨越这条出边,直到len[tran[now][S[n-rem+1]]] ≤ rem,因为当前待插入新后缀去掉尾字符就是已插入的隐式后缀,这条边肯定能走通。对应于原串后缀的节点x称为。
2024-12-06 13:32:04
743
原创 左偏红黑树插入新节点后的维护操作
开始将当前节点指向新节点,然后递归向上维护,在整个递归维护过程中,会保持整个树的性质与刚插入时一样:即除了当前节点与其父节点可能会违反性质23以外整颗树都是合法的(当前节点如果没有父节点直接退出递归)。② 只违反性质2,右旋一次,再翻转一次颜色,这样ABCD的黑深度保持不变,但顶上那个节点的颜色变了,将当前节点指向最后方框里的那个节点继续递归。③ 同时违反性质23,先左旋再右旋,再翻转一次颜色,这样ABCD的黑深度保持不变,同②一样将当前节点指向最后方框里的那个节点继续递归。3. 黑节点的右孩子也不为红。
2024-11-22 14:22:22
139
原创 红黑树(RB Tree)插入新节点后的维护操作
5. 当前节点N的父节点P为红且叔节点为黑且N和P为同侧节点,此时G必为黑节点,这里只说均为左侧的情况,右侧同理:先右旋G,再将P涂黑将G涂红,此时同时满足性质1和2(子树根节点的颜色依旧为黑,节点插入前的红黑树是合法的),结束递归。6. 当前节点N的父节点P为红且叔节点为黑且N和P为异侧节点,同样只说一种对称的情况:如下图,N为P的右儿子,P为G的左儿子,将P左旋一下,将当前节点指向P,则完全变成了第5种情况,按先前的方式处理即可。1. 红节点的子节点为黑(这意味着红节点的父节点也为黑)。
2024-11-21 03:32:08
196
原创 最小回文划分(回文树)
2.设x是在i位置的等差数列回文后缀子集中最长的那个,则在计算dp[i]时,所需要参考的所有dp[i-len[v]](slink[v]==slink[x]),除了dp[i-len[slink[x]]-diff[x]](x所在等差数列的最短回文后缀长度就是len[slink[x]]+diff[x]),在计算dp[i-diff[x]]时均已经被参考过。如果diff[x]==diff[fail[x]], 则g[x]=min(g[fail[x]],dp[i-len[slink[x]]-diff[x]])
2024-10-22 21:18:08
439
原创 Lyndon分解求最小表示法(Python)
假设S的Lyndon分解为:s=s(1)+s(2)+……+s(k),那么最小表示法的首字符肯定是某一个Lyndon串的首字符,因为Lyndon串严格小于其非空真后缀。明显应该选择s(p)在最前。假如s(p)的首字符序号为i,那么这个i值其实就是Duval算法中外循环最后一次循环开始前的i值。前置:最小表示法,Lyndon分解,Duval算法。
2024-10-15 23:11:35
165
原创 Codeforces 39I Tram
对于非树边(u,v)且u,v∈S,要满足题解第一段的要求根据同余定理那么t只能取abs(d[u]+1-d[v])的约数,t取最大则t是所有abs(d[u]+1-d[v])的gcd。设t满足题目要求,那么此时从1出发到某点的所有路径长度(mod t)必是一个定值(否则因为出度至少为1,电车可以一直走那么电车一定可以走到某点,从1出发到该点的路径长度有(mod t)=0和(mod t)≠0的两种情况,那么无论在该点是否安装摄像头均不满足题意)。St-1是没有交集的,且S=S0∪S1∪……
2024-06-26 18:15:47
253
原创 Codeforces 38G Quene
n个人先后到地排队,每个人有不同的事情重要度ai,如果后到的人ai大于前面的人,那么就会发生交换事情更重要的人会往前挪一个位置,这种交换最多会发生ci次,问最后的序列。当ai大于子树最大a值,且ci大于右子树的大小,则走左边同时ci减去右子树的大小+1,否则走右边,遇到空节点时插入即可。构建BST,每个节点除了key值维护以下信息:子树的大小,子树的最大a值。剩下的就是平衡BST了,有很多种方法选一种即可。
2024-06-22 16:08:05
230
原创 Codeforces 57C Array
上式可以看成从2n-1数量的小球里选出n-1个小球,即C(2n-1,n-1)。注意计算C(2n-1,n-1) MOD 100000007需要用到取模逆元。然后用隔板法求这k个数字各自的数量,有C(n,k)*C(n-1,k-1)。求n个数字,每个数字取值范围为[1,n],不下降序列与不上升序列的数量。首先设序列里有k个不同的数字,即从1到n里选k个数出来,有C(n,k)。
2024-06-22 15:48:22
201
原创 Codeforces 55D Beautiful numbers
第三维的规模为252。假设高位数字为A,填的低位数字为B,则(A*10^k+B) %2520=((10A)%2520*10^(k-1)+B)%2520=((A%252)*10^k+B)%2520,即高位数字对最终结果 MOD 2520的影响仅与其MOD 252的结果有关。假设一个数C的各位数字最小公倍数为lcm,则C%lcm=(2520M+P)%lcm=(2520%lcm*M+P)%lcm=P%lcm,而P=C%2520。一个十进制数能被自身非零数整除则是一个美丽数,求[l,r]区间的美丽数个数。
2024-06-17 14:54:52
169
原创 Codeforces 38H The Great Marathon
n个人在n个城市之间跑马拉松,每个人的起点不同终点任意但必须走最短路,每个人速度相同,按完成时间和起点编号排名,发g∈[g1,g2]个金牌,发s∈[s1,s2]个金牌,发个n-g-s个铜牌,问有多少种不同的奖牌发放方案。注意手动地G[i]=1,S[i]=0,B[i]=0,G[j]=0,S[j]=0,B[j]=1,防止i选手和j选手去拿这次枚举情况下不该拿的牌子。dp[k+1][x][y]=0 if B[k]==0 # 多了一个人但是金银牌数量不变又不能拿铜牌那就没牌了。
2024-06-08 16:50:13
499
原创 Codeforces 41E 3-cycles
因为任意没有三元环的简单图都可以被转化为边数相同顶点数相同的二分图,而且二分图也是没有三元环的,所以任意n个顶点的没有三元环的简单图的边数都不大于n个顶点的二分图的最大边数,于是原问题也被转化为了求n个顶点的二分图的最大边数,这就比较简单了。假设图G的最大出度点为v~0~,最大出度为m,那么与v0相连的m个顶点互不连接,设这m个顶点为集合X,我们可以把集合V-X的所有边都转向与X连接(V-X的出度都不大于m),于是G被转化为了一个二分图。n个顶点的简单图,求没有三元环的最大边数,并且输出这些边。
2024-05-08 02:45:49
387
原创 Codeforces 37D Lesson Timetable
有1到M编号的教室,第一节课教室i有Xi个人上课,每个人第一节课的教室编号小于等于第二节课的教室编号,教室i最大容纳数量Yi,Yi>=Xi,求不同的方案数。先不管第一节课的方案数量,最后再乘就行了,先假设已经安排好了第一节课求第二节课的方案数。即前i-1个教室已经选好j-k了个人,再从Si-j+k的备选池里选出来k个人放到教室i。f[i][j]表示安排好了前i个教室,已经安排了j个人的方案数。可以提前用组合数递推公式计算comb矩阵避免写高精度。
2024-05-02 21:05:47
243
2
原创 Codeforces 30D King‘s Problem?
我们尝试将k点挪到上述路径的起点或终点,然后计算挪点所需要的距离加路径本身长度的最小值。x轴上有n个点,轴外有一个点n+1,问从k点出发遍历全部的最短路径。当1≤k≤n时,我们先不考虑出发点,先看看遍历全部点的可能最短路径。首先特判一下k==n+1,这里很简单不赘述。不会证明,反正直觉上是这样的。其中Bmin=Amax+1。
2024-04-25 00:39:30
212
1
原创 Codeforces 35C Fire Again
n*m的森林,有k个火源,单位时间上下左右各蔓延一次,求任意最后被烧到的树。爆搜,注意到距离每个火源最远的树都在森林边缘,因此只需要搜4个边缘即可。多源BFS,最后出队列的那颗树就是。
2024-04-19 11:24:39
165
原创 Codeforces 31E TV Game
初始状态dp[0][0]=0, 除开初始状态dp数组初始值最好设为负数因为输入数字串有0。最大和是dp[2n][n],状态回溯输出答案即可。2*n长度的数字串a,A和B分别选出n个数字组成子数字串,求两子数字串的最大和。乍一看数据规模以为是状压,结果上手发现是O(n^2)的DP。
2024-04-19 11:07:40
146
原创 Codeforces 29E Quarrel
可以增加一个状态a表示此时A先走B还没走,假设b(i,j)是从状态(0,n-1)到状态(i,j)的最小深度,那么有a(i,j)=min{b(i.neibor,j)},b(i,j)=min{a(i,j.neibor) | j.neibor≠i}+1,从交替更新ab状态可以避免去求i.neibor和j.neibor的全部组合,降低复杂度。因为边权全部是1,直接BFS从(0,n-1)搜到(n-1,0)即可。n个结点,A从结点0走到结点n-1,B从结点n-1走到结点0,中途不能停留在同一个结点,求最短路径。
2024-04-16 22:11:06
229
原创 Codeforces 19E Fairy
假设单返祖边环(u1,v1)是偶环,单返祖边环(u2,v2)是奇环,则按单返祖边统计,只有u2→lca(u1,u2),v1→v2被计入答案边,耦合出的双返祖边环为奇环,依然会给u2→lca(u1,u2),v1→v2的奇环数+1,不影响答案边。假设单返祖边环(u1,v1)是奇环,单返祖边环(u2,v2)是偶环,则按单返祖边统计,只有u1→lca(u1,u2)被计入答案边,耦合出的双返祖边环为奇环,依然会给u1→lca(u1,u2)的奇环数+1,不影响答案边。无向图中的非树边都是返祖边,以下均称为返祖边。
2024-04-02 08:54:41
699
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人