2020.09.05【省选组】模拟

T1:首先用tarjan求出所有的点双,然后建圆方树。具体的建法是将当前点双的割点作为父亲向一个新建的方点连边,然后方点在想点双中其他点连边。

在建好圆方树之后我们就树形dp。设f[i]表示从i的子树到i的最长链的长度。对于每个x,如果x为圆点则像常规一样转移;若x为方点则要处理一下:把当前方点对应的点双中的点拉出来排成一列,然后复制一遍(处理环的情况)。接着我们枚举i、j(i<j),若j-i<=n/2则用f[i]+f[j]+j-i去更新ans。求f[x]类似。至此这道题就做完了。

 

T2:我们只讨论左小右大的情况,左大右小的直接将整个数列去相反数即可。

首先设L[x]表示从x往前第一个比a[x]大的位置+1,R[x]表示往右第一个比a[x]小的位置-1。

若一个区间[l,r]是合法的,那么必定存在R[l]>=r且L[r]<=l。反过来推也是对的。

现在我们枚举右端点r,每次r往后移一位时,对于那些R[x]<r的位置以后都不能再用了。而L[r]~r中那些可以用的位置的最大长度则会全部更新为右端点为r时的长度。这样我们就可以用一颗线段树来维护答案,线段树的每一个节点维护当前区间能用的最靠左的左端点,区间最大答案,以及区间修改标记。我们首先把R单调排序,每次右移r时先删去那些以后再也不能用的左端点,然后区间修改L[r]~r。每次查询的时候就查询[l,r]的最大答案即可。

 

T3:李超树模板题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值