Codeforces Round #654 (Div. 2) F. Raging Thunder

题目

https://codeforces.com/contest/1371/problem/F

有一个长度为n的传送带,每个位置有一个方向(’<’或’>’表示向左或向右)。n个位置中间以及两端共有n+1个洞。当一个球落在上时,它会被往左传送,一直传送到头或者遇到一个往右的传送带,然后就会落到中间那个洞里,或者头上的洞里。

有q个操作,每个操作给定l和r,其将[l,r]之间的传送带反向(向左改为向右,向右改为向左),然后在[l,r]每个位置上都放一个球。这些球会落到某些洞里去,要求输出球最多的那个洞有多少个球。每次操作之后,反向了的传送带仍然保留,但洞里的球会消失,不会影响下次查询。

做法

这题目出的就跟线段树似的,所以肯定用线段树做了。

先不考虑反向操作,只考虑球回落到哪个洞里。分析可以发现,形如’>>>><<’这样的结构,球就会都落到中间那个洞里。而这样的结构的分界点是’<>’。我们只需要维护这种结构的最大长度即可。因此,需要维护的东西有:

  • 左右端点的方向
  • 最左边的这种结构的长度
  • 最右边的这种结构的长度
  • 当前区间的答案

合并的时候,分两种情况(是’<>’与不是’<>’分开讨论维护即可)。

现在有反向操作,如果反向了,上面维护的结构和分界点就不对了!那该怎么办呢?但是我们建树的时候,每个区间都维护一个正的和一个反的信息,反向操作就直接swap一下就行了。

代码

https://codeforces.com/contest/1371/submission/86937856