P5069 [Ynoi2015] 纵使日薄西山

2024-04-11 8713阅读

纵使日薄西山,我也想保护你..

P5069 [Ynoi2015] 纵使日薄西山 第1张
()

先不考虑单点修改

手玩一下样例

P5069 [Ynoi2015] 纵使日薄西山 第2张
()

可以发现你一直操作一个数的结果是和答案一样的

可以大致证明一下

x y z

如果选择y操作,那么x,z必然不能操作,因为x,z会和y一直减少,只有y做出了贡献,所以我们的答案应该是选的数之和

因此应该只有2种操作方法

操作1 ,3,5,7...

操作2,4,6,8...

也就是维护一个奇偶性相同的单增或者单减序列

挺抽象的,这种做法待补

我们可以用线段树来维护需要被操作的值(合并很妙)

我们先思考一下,我们需要维护哪些值,左端点有没有被操作的,右端点有没有被操作的,以及如果左端点需要被操作的贡献是多少,右端点需要被操作的贡献是多少,如果两端都被操作的贡献是多少,因此我们维护四颗线段树,seg[N=a[mid+1]){ seg[id][2].lf=seg[tl(id)][0].lf; seg[id][2].val=seg[tl(id)][0].val+seg[tr(id)][3].val; }else{ seg[id][2].lf=seg[tl(id)][2].lf; seg[id][2].val=seg[tl(id)][2].val+seg[tr(id)][2].val; }

else()直接转移

if(seg[tl(id)][0].rf && seg[tr(id)][2].lf){
        if(a[mid]>=a[mid+1]){
            seg[id][2].lf=seg[tl(id)][0].lf;
            seg[id][2].val=seg[tl(id)][0].val+seg[tr(id)][3].val;
        }else{
            seg[id][2].lf=seg[tl(id)][2].lf;
            seg[id][2].val=seg[tl(id)][2].val+seg[tr(id)][2].val;
        }

4.if() 要管左边的左子树有右端点标记,要管右边的右子树有左端点标记

不用考虑左右端点转移

(i)左边大于等于右边

答案求和是左边(管左边)+右边(管两边)

(ii)右边大于左边

答案求和是左边(管两边)+右边(管右边)

if(seg[tl(id)][1].rf && seg[tr(id)][2].lf){
        if(a[mid]>=a[mid+1]){
            seg[id][3].val=seg[tl(id)][1].val+seg[tr(id)][3].val;
        }else{
            seg[id][3].val=seg[tl(id)][3].val+seg[tr(id)][2].val;
        }

else()直接转移

 seg[id][3].val=seg[tl(id)][1].val+seg[tr(id)][2].val;

讨论结束

可以发现只有中间存在重叠的情况才需要讨论左右端点的标记转移,其他情况直接转移即可

文字描述很拉垮,可以直接看码.

完整代码

#include
#include
#include
#include
#include
#include
#define INF (1ll

    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]