csp-s模拟96

T1:
  随便推一下就行了,个人感觉拆成二维前缀和更好推
 
T2:
  显然区间内最大匹配最大,次大匹配次大,以此类推,最优
  贪心的让每个区间人尽量多也是对的

  考虑对于一个左端点,如何快速找到最靠右的合法右端点
  (推了半天式子发现增量法并不能用QAQ)

  直接二分肯定是不行的,因为可以每次只拓展一个,复杂度就会变为\(O(n^2log^2n)\)
  考虑倍增套二分
  即:用倍增确定二分区间

  check时暴力sort就行了,复杂度为\(O(nlog^2n)\)
 
T3:
  首先有个结论:小B只会封掉小A当前所在节点连接的一条路
  设\(f_i\)表示i点到n点的答案,\(l_{i,j}\)表示(i,j)这条边的长度,\(dis_i\)表示i到n的最短路
  如果我们可以处理出\(del_{i,j}\)表示删掉(i,j)这条边后i到n的最短路
  那么就可以用dp:\(f_i=min\{ max(f_j+l_{i,j},del_{i,j}) \}\) 计算答案

  考虑如何计算\(del\)数组
  若删的边不在i到n的最短路上,你们\(del_{i,j}\)的值就是\(dis_i\)
  若删的边在最短路上,且根据前文结论该边一定与i相连,那么我们的问题就转化为了:
  求不经过最短路树上最后一条边的最短路

  这个问题比较常见,有两种解决方法:
  1.树剖 2.并查集(思想)
  树剖的思路很简单:
  跑出最短路树,以n为根,计算\(dep_x\)表示x到根的距离
  因为最后任意点x的答案可以表示为\(max\{dep_a+dep_b+l_{a,b}-dep_x\}\)
  所以对于每一条非树边(a,b),可以更新的点为a-b除lca外的所有点,用\(dep_a+dep_b-l_{a,b}\)更新既可

  并查集的思路就很巧妙了:
  考虑将非树边按照\(dep_a+dep_b-l_{a,b}\)从小到大排序,那么每个点只需要被更新一次就可以了

posted @ 2019-11-12 09:51  G_keng  阅读(120)  评论(0编辑  收藏  举报