码迷,mamicode.com
首页 > 其他好文 > 详细

【Codeforces 650 D】Zip-line

时间:2019-04-30 01:01:44      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:定义类   区间查询   cas   优化   结束   and   test   单点   case   

题意:给一个序列以及\(n\)个查询,每一个查询是问(假装)把第\(a_i\)个数改为\(b_i\)之后原序列的最长上升子序列的长度。

思路:线段树优化\(dp\)

肯定离线做啊。

首先我们考虑\(dp\)的状态是\(dp_L(i)\)表示以第\(i\)位为结束的最长上升子序列的长度和方案数\(mod\ 998244353\)

之所以方案数要模某个数是因为这个方案数太大太大了,肯定爆\(long\ long\)

就因为这个我\(wa\)了一次\(test\ case\ 13\)

开心的不得了呢

\(dp_R(i)\)的定义类似,只是以\(i\)为开始而已。

考虑转移,以\(dp_L\)为例。

\(dp_L(i)=dp_L(j)+1\)当且仅当\(j<i and a_j < a_i\)

那么这肯定可以用线段树来维护啊。

只需要用一个单点修改、区间查询的zkw就好了。

那么我们考虑把\(i\)换掉之后会发生什么。

首先新的LIS可以分成两部分考虑:

  • 必须包含新的数,那么就是我们可以考虑把\(i\)按照原来的\(dp\)方式转移,只不过需要添加查询数的\(dp\)值。
  • 不能包含新的数,那么有点难考虑。
    但是我们知道一个性质:如果我们所有的原来的LIS都经过这原来的数,
    那么现在不经过原来数的LIS最大也不会超过原来的-1,而且是肯定能够达到的。
    我们只需要统计经过原来这个数的LIS个数。
    也就是\(dp_L(i)*dp_R(i)\)

然后取必须包含这一位和必须不包含的\(max\)就是答案了。

【Codeforces 650 D】Zip-line

标签:定义类   区间查询   cas   优化   结束   and   test   单点   case   

原文地址:https://www.cnblogs.com/denverjin/p/10793592.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!