金华集训正睿Day2 分治&图论&字符串


讲课

1.分治

common分治

也就是对于每个子问题,在中间划一刀,然后分成两段,把区间中从mid开始维护一些奇奇怪怪的值,一般来说是最大前后缀、最小前后缀什么的。在中间的交集处理完毕后开始递归两边。总的来说就是乱搞

  • 切mid
  • 处理越过mid的答案,统计
  • 递归解决

二分

分数规划

普通二分学的好好地,突然开始鬼畜。

分数规划问题,统计值形为分式的表达式最值,一通转换后获得一个便于维护的表达式。

  • 维护 a [ i ] b [ i ] \frac{a[i]}{b[i]} b[i]a[i]最大
  • a [ i ] b [ i ] > = m i d \frac{a[i]}{b[i]}>=mid b[i]a[i]>=mid
  • a [ i ] > = m i d ∗ b [ i ] a[i]>=mid*b[i] a[i]>=midb[i]
  • a [ i ] − m i d ∗ b [ i ] > = 0 a[i]-mid*b[i]>=0 a[i]midb[i]>=0

对就是这玩意。

然后就能开始乱搞了

最小区间圆覆盖

挂、、、

整体二分

例题询问第k大

二分答案<=mid的数有没有k个。

但好像不止如此,同学博客目前没看到解释的很清楚的,挂了挂了

cdq分治

听说精髓就是考虑左边对右边的贡献,它可以处理各种缺1缺点缺边缺答案缺正解(???)问题。

太过玄妙没有听谢谢

点分治

点分治效率优秀,无怪乎它找了重心作为起点,不然铁定是要T飞的。

区间上的分治找到一个中心点,处理了跨区贡献后递归子问题,而点分治的精髓也在于分治,将数据规模减小,每次递归成为子树的问题,边界处理没有问题。

是的,每次以重心为界处理并递归下每颗子树,重新求解重心,重新计算,看起来与区间分治差别不大的样子呢。

关于它与树形dp之间有一些共性,因为都是在节点上处理与子树的关系。但一般来说,树形dp的题多是可以用点分治解决,而点分治得问题自是麻烦些,但好像也是可以由树形dp解决。

个人而言,点分治这个算法最近才接触,树形dp相对而言熟悉些,更加熟练,但是点分治熟练掌握是十分重要的。

时间分治

刚才dls讲了一下,时间分治中,因为添加、删除很麻烦,所以用另一种方法:按时间。时间轴中,某值在[l,r]区间内存在。 这做法真令人头秃,这tm也能分治?


2.图论

- 1.最短路变种:

也就是动态删边删点最短路

  • 动态删边。如果该边不在最短路径上不用管,如果在的话寻找最小替代,从断点处x,y,用dis[1,x]+dis[x,y]+dis[y,n]更新替代??

看起来是这么一回事,老师讲的没怎么听懂,这是我自己的理解。话说这题貌似是用cdq分治搞啊(算了不管了)

  • 动态删点。对于该点不在路径上的情况依然不用考虑。而不在则寻找最小替代。题目中多出一个无环的条件,这题要
- 2.例1。

题目:给定⼀张有向带正权拓扑图,求有⼏条 1 到 N 的路径的长度<= 1 到 N 的最短路+K

暴力&正解:

  • 设 f [ x ] [ L ] 表 示 1   x 路 径 长 度 为 L 设f[x][L]表示1~x路径长度为L f[x][L]1 xL
  • f [ x ] [ L ] − > f [ f[x][L]->f[ f[x][L]>f[
  • 要 求 L + d i s ( x , n ) − d i s ( 1 , n ) < = k ; 要求L+dis(x,n)-dis(1,n)<=k; L+dis(x,n)dis(1,n)<=k;
  • d i s ( 1 , n ) < = d i s ( x , n ) + d i s ( 1 , x ) dis(1,n)<=dis(x,n)+dis(1,x) dis(1,n)<=dis(x,n)+dis(1,x)
  • L + d i s ( x , n ) − ( d i s ( 1 , x ) + d i s ( x , n ) ) < = k L+dis(x,n)-(dis(1,x)+dis(x,n))<=k L+dis(x,n)(dis(1,x)+dis(x,n))<=k
  • L − d i s ( 1 , x ) < = k L-dis(1,x)<=k Ldis(1,x)<=k
  • d i s ( 1 , x ) < = L < = d i s ( 1 , x ) + k dis(1,x)<=L<=dis(1,x)+k dis(1,x)<=L<=dis(1,x)+k
  • 对 于 第 二 维 L , 有 效 取 值 只 有 k + 1 种 对于第二维L,有效取值只有k+1种 Lk+1
  • 所 以 f [ x ] [ L − d i s ( 1 , x ) ] 所以f[x][L-dis(1,x)] f[x][Ldis(1,x)](0~k)
  • 路 径 长 度 d i s ( 1 , x ) + v ; 路径长度dis(1,x)+v; dis(1,x)+v;
  • f ( x , v ) − > f ( y , d i s ( 1 , x ) + v + w ( x , y ) − d i s ( 1 , y ) ) f(x,v)->f(y,dis(1,x)+v+w(x,y)-dis(1,y)) f(x,v)>f(y,dis(1,x)+v+w(x,y)dis(1,y))
  • 求 f [ N ] [ d i s ( 1 , n ) … … d i s ( 1 , n ) + k ] 求f[N][dis(1,n)……dis(1,n)+k] f[N][dis(1,n)dis(1,n)+k]
- 3.最短路变种2(删点):

??:

  • 1.对于所有边,求出长度L,[sl,sr]线段树维护最小值
  • 2.L=dis(1,x)+dis(y,n)+w
- 4.三元环计数:

1。

  • 1.大小点:???

  • 2.设原图为G[x]:d[1…n]

  • 排序,关键字(d[i],i),求每个点是第几小。

  • D[x]:(x,y)

  • 如果rank[x]y

  • else rank[x]>rank[y]: y->x

  • |D[x]|<=sqrt(m)

伪代码(核心部分):

for 1 to x do 
 if (y∈D[x])res[y]=1;
for y∈D[x] do  
 for z∈D[y] do
   ans+=res[z];
- 5.四元环计数
for x=1 to n // n
 for y∈G[x] 
  for z∈D[y] 
   if(rank[x]
- 6.例子

题目:你现在很想知道⼀个数列 A[1…N] 是啥,但是需要花费代
价去获取情报,你可以花费 Cost[L][R] 的值去得到 A[L…R]
的和,给定 Cost,求最少花费多少代价才能确定 A[1…N]
• N<=1000,Cost[L][R]<=10^9

解:

  • 知道A[l…r]也就是知道S[r]-S[l-1]的值,(S为前缀和数组)
  • 每次将l-1与r连边,表示可以互相推得。
  • 要知所有关系,则将所有边加入后做一遍最小生成树,(因为要与1号相连)
prufer序列

表示一棵无根树与序列一一对应的关系。

  • 构造:每次找到一棵最小的叶子,删去后加入与其相连的点到prufer序列中,直到最后只有两点。
  • 用prufer序还原树的步骤:对于prufer序从前往后,每次找一个之后的prufer序中没有出现过且之前没有标记过的最小的节点,标记这个点,和当前prufer序的这个点连边,最后找两个度数不够的点,把他们连起来(其实就是顺着做prufer序的过程连边)。
  • 容易得知,序列中出现次数+1就是该点度数。
欧拉回路
二分图

判断奇环,判断偶环

Hall引理
7.边的染色
8.练习题

3.字符串

KMP字符匹配

寻找最小循环节,(n-fail[n]也是循环节,s[1]=s[n-fail[n]+1]),也就是最长相等的前后缀。

  • 寻找最小的P,使得s[i]=s[i-p];
  • 纯循环节:n是n-fail[n]的倍数
例题
  • 1. 给定⼀个字符串 S,对于每个前缀S[1…i]求出:有⼏对前后缀相等且
    不重叠. |S|<=1000000

  • 2. 给定⼀个 m 位数字串 S,求有⼏个⻓度为 n 的字符串 T,满⾜ S 不
    是他的⼦串. m<=20. n<=10^9

  • 3. 有⼀个串 S,给定 S[1…i] 的最⼩循环节 d[i],构造⼀个字典序最⼩的
    S. |S|<=10^6

  • 4. 有⼀个串 S,定义⼀个优秀的拆分是将⼀个串表示成 AABB 的形式,
    求 S 的所有连续⼦串的优秀的拆分的个数之和. |S|<=2000

  • 5. AC自动机

后缀数组

挂掉……[哭卿卿]

n ∗ ( n + 1 ) 2 − ∑ i = 1 n − 1 h [ i ] \frac {n*(n+1)}{2}-\sum_{i=1}^{n-1} h[i] 2n(n+1)i=1n1h[i]

你可能感兴趣的:(讲课总结)