Codeforces1736C2. Good Subarrays (Hard Version)
题解:
记 \(ans[i]\) 为以 \(i\) 为结尾最长的好的数列长度
观察发现,以 \(i\) 为结尾的好的数列,长度可以是 \(1,2,3,...,ans[i]\)
这个很好理解,因为如果区间数列 \([l,r]\) 是好的,那么 \([l+1,r]\) 一定也是好的。
我们要求的答案也就是 \(\sum ans[i]\) 。
我们先来考虑 \(ans[i]\) 是怎么求,显然有 \(ans[i]=min(ans[i-1]+1,a[i])\) ,要么在前面的最长的好的数列的基础上往后添一个,要么它最多只能有 \(a[i]\) 的长度。
当强制 \(ans[i]=a[i]\) 然后按照上述方法算出后面的位置的 \(ans\) 时,记 \(sum[i]=\sum_{j=i}^nans[j]\)
\(sum[i]\) 数组也比较好求,倒序求出来,可以借助线段树
考虑修改操作,若修改的位置是 \(x\) ,显然 \(x\) 以前的答案不会改变,若 \(x\) 位置答案变成了新的 \(ans[x]\) ,那么后面的答案会变成形如 \(ans[x]+1,ans[x]+2,...,ans[x]+k-1,a[x+k]\)
找到第一个 \(k\) 满足 \(a[x+k]\le ans[x]+k\) 即 \(ans[x+k]-x-k\le ans[x]-x\) ,那么 \(x\) 及以后的答案就变成了 \(\sum_{i=0}^{k-1}(ans[x]+i)+sum[k]\)
找 \(k\) 可以用线段树,然后这个题就做完了,时间复杂度 \(O(n\log n)\)
标签:Good,数列,Subarrays,sum,Version,ans,Codeforces1736C2 From: https://www.cnblogs.com/xoslh/p/16783124.html