[UESTC]Another LCIS[线段树][区间合并][成段修改]

终于体会了什么是WA至死.....orz

14WA in 3Days

题意:

给出n个数, a 区间同时加上d, q 询问区间LCIS.

思路:

成段修改还是用标记.

区间合并除了PushUp需要判断相接, query也需要. 而且有两种实现:

一是涉及哪个儿子就query, 一直取最大(此代码),二是若只涉及一个儿子, 返回query那个儿子; 否则两边&中间取最大. 有点小差别~

本来我想原数列直接保存就行, 因为每次只修改区间的端点, 而对于每一个标记, 可以维持儿子端点只被修改一次(中间的重复可以判断). 但是一直WA...目前还没想通是哪错了><

AC的方案是树中增加左右端点, 这样就可以严格分层修改, 不会有隐患.

query中lmax写成rmax....此等细部暗箭难防啊.......只能苦练火眼金睛以及严谨的编码能力....

#include <cstdio>  
#include <algorithm>  
using namespace std;  
#define lson l, m, rt<<1  
#define rson m+1, r, rt<<1|1  
const int MAXN = 111111;  
int mmax[MAXN<<2],lmax[MAXN<<2],rmax[MAXN<<2],add[MAXN<<2],lv[MAXN<<2],rv[MAXN<<2];  
int T, L, R, V, cas, N, Q;  
char op[5];  
void PushUp(int w, int rt)  
{  
    lmax[rt] = lmax[rt<<1], rmax[rt] = rmax[rt<<1|1];  
    lv[rt] = lv[rt<<1], rv[rt] = rv[rt<<1|1];  
    mmax[rt] = max(mmax[rt<<1], mmax[rt<<1|1]);  
    if(rv[rt<<1]<lv[rt<<1|1])  
    {  
        if(lmax[rt<<1]==w-(w>>1))  
            lmax[rt] += lmax[rt<<1|1];  
        if(rmax[rt<<1|1]==w>>1)  
            rmax[rt] += rmax[rt<<1];  
        mmax[rt] = max(mmax[rt], rmax[rt<<1]+lmax[rt<<1|1]);  
    }  
}  
void build(int l, int r, int rt)  
{  
    add[rt] = 0;  
    if(l==r)  
    {  
        scanf("%d",&lv[rt]);  
        rv[rt] = lv[rt];  
        mmax[rt] = lmax[rt] = rmax[rt] = 1;  
        return;  
    }  
    int m = (l+r)>>1;  
    build(lson);  
    build(rson);  
    PushUp(r-l+1,rt);  
}  
void PushDown(int rt)  
{//直接在那上面改大概是有悖线段树的思想吧> <  
    if(add[rt])  
    {  
        add[rt<<1] += add[rt];  
        add[rt<<1|1] += add[rt];  
        lv[rt<<1] += add[rt], lv[rt<<1|1] += add[rt];  
        rv[rt<<1] += add[rt], rv[rt<<1|1] += add[rt];  
        add[rt] = 0;  
    }  
}  
void update(int L, int R, int V, int l, int r, int rt)  
{  
    if(L<=l && r<=R)  
    {  
        add[rt] += V;  
        lv[rt] += V;  
        rv[rt] += V;  
        return;  
    }  
    PushDown(rt);  
    int m = (l+r)>>1;  
    if(L<=m)    update(L, R, V, lson);  
    if(m<R)     update(L, R, V, rson);  
    PushUp(r-l+1,rt);  
}  
int query(int L, int R, int l, int r, int rt)  
{  
    if(L<=l && r<=R)  
    {  
        return mmax[rt];  
    }  
    PushDown(rt);  
    int m = (l+r)>>1;  
    int ans = 0;  
    if(L<=m)  
        ans = max(ans, query(L,R,lson));  
    if(R>m)  
        ans = max(ans, query(L,R,rson));  
    if(rv[rt<<1]<lv[rt<<1|1])  
    {  
        ans = max(ans, min(R, m+lmax[rt<<1|1]) - max(L, m-rmax[rt<<1]+1) + 1);  
    }  
    return ans;  
}  
int main()  
{  
    scanf("%d",&T);  
    cas = 0;  
    while(cas++<T)  
    {  
        printf("Case #%d:\n",cas);  
        scanf("%d %d",&N, &Q);  
        build(1, N, 1);  
        while(Q--)  
        {  
            scanf("%s",op);  
            if(op[0]=='a')  
            {  
                scanf("%d %d %d",&L,&R,&V);  
                update(L, R, V, 1, N, 1);  
            }  
            else  
            {  
                scanf("%d %d",&L,&R);  
                printf("%d\n",query(L, R, 1, N, 1));  
            }  
        }  
    }  
    return 0;  
}  


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
互联网络程序设计是指在互联网上进行程序开发和设计的过程。UESTC则是我国的一所著名高校——电子科技大学。 互联网络程序设计 uestc包含了两个主要的方面:互联网络和程序设计。互联网络是指将多个计算机网络通过通信链路互相连接起来,实现信息共享和资源共享的网络系统。程序设计是指根据需求和目标,通过编写代码和设计算法,实现计算机程序的过程。 互联网络程序设计 uestc的学习内容主要包括以下几个方面: 1. 网络知识:学习互联网络的基本概念、原理和协议,如TCP/IP协议、HTTP协议等。掌握网络编程的基本技术,能够编写网络应用程序。 2. 数据通信:学习数据通信的基本原理和技术,包括数据传输的方式、数据压缩和加密等。了解网络安全和数据保护的基本知识。 3. 程序设计:学习编程语言和开发工具,如Java、C++和Python等。掌握常用的编程技巧和方法,能够设计和实现复杂的网络应用程序。 4. Web开发:学习Web开发的基本知识和技术,包括HTML、CSS、JavaScript等。能够设计和实现交互式的Web应用程序。 5. 数据库技术:学习数据库的基本原理和技术,如SQL语言和数据库管理系统。能够设计和管理数据库,实现数据的存储和检索。 通过学习互联网络程序设计 uestc,可以掌握互联网应用开发的基本技能,具备设计和实现网络应用程序的能力。这对于目前互联网行业的人才需求来说是非常重要的,也为学生提供了广阔的就业和创业机会。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值