[JSOI2009]等差数列【差分+线段树】

博主分享了在JSOI2009竞赛中遇到的一道关于等差数列的难题,通过线段树和差分解决。在解决问题过程中遇到了一些挑战,如正确答案的计算量比预期小,以及如何维护零散数列长度。经过一周的努力,最终成功解决。文章总结了从题解中学到的经验,包括快读、线段树节点的重载加号、差分数组的边界处理等,并强调了避免手残的重要性。同时,博主表示将专注于提升自己的网络流技术。
摘要由CSDN通过智能技术生成

作为水到一等的弱省OI蒟蒻,甚至以为自己能听懂SDWC的省选班。去了以后发现除了搜索、仰望大佬和看妹子(还真有妹子很不错)以外啥都不会…每天都是听一小时之后弃疗。
然而唯一有基础的线段树…也是一上来“大家都会写线段树吧”然后丢一道黑题(也就是这道)。同伴在身边大呼简单:“也就差分比较难想。”于是当天晚自习,我们点开了那道题…
写完统计差分数组中连续相等数的长度获得了一堆Wonderful Answer后…发现正确答案比我们的输出小一半后百思不得其解…点开题解,发现要维护什么零散数列长度…同伴果断放弃,我也知道考场上不可能有时间给你看题解,不过面对自己百余行代码不忍弃之…然后怼了一周,终于a掉了。
唉,手残毁一生,特此留念。


题目编码不同,那就不复制了。
https://www.luogu.org/problemnew/show/P4243


正文也没啥可以写的,各路大佬写得都很透彻,我的码力不足,常数巨大,那我总结一下看题解得到的经验。

1.各路大佬都喜欢快读,看来这种水平的题目,刷题者已经习惯快读了;
2.当线段树向上合并操作比较麻烦的时候,可以在线段树节点的结构体中重载加号(我在这道题没写,导致pushup和query的时候写了两遍…);
3.差分数组中第一项为原数组第二项与第一项之差,以此类推,所以差分数组中只有n-1个元素;
4.注意边界问题的处理,区间加的时候看看边界,比如第一项没有与前一项的差什么的;
5.千万不能手残!!!!!!!!!!!!!

#include<cstdio>
#include<algorithm>
#define lll long long
const lll maxn=100002;
lll tt[maxn],a[maxn],n,m,x,y,s,t,i;
char ch[3];
struct node{lll l,r,t,ll,rr,len;};
struct segtree{  
    #define lson (o<<1)
    #define rson (o<<1|1)
    #define mid ((l+r)>>1)
    lll addv[maxn<<2],vall[maxn<<2],valr[maxn<<2],sumt[maxn<<2],suml[maxn<<2],sumr[maxn<<2],lenv[maxn<<2];
    inline void pushup(lll o){
        lll lenl=lenv[lson],lenr=lenv[rson];
        lenv[o]=lenl+lenr;//此处手残多处,有很多细节
        suml[o]=sumr[o]=0;                                   
        vall[o]=vall[lson];valr[o]=valr[rson];sumt[o]=sumt[lson]+sumt[rson];
        if(suml[lson]==lenl&&sumr[rson]==lenr){      
            if(vall[rson]==valr[lson]){sumt[o]=1;suml[o]=lenl-1;sumr[o]=lenr-1;}
             else{sumt[o]=0;suml[o]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值