HDU 1540(线段树+区间合并)学习记录

Posted iamamori

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 1540(线段树+区间合并)学习记录相关的知识,希望对你有一定的参考价值。

学习了线段树的新姿势,记录一下

参考blog:https://blog.csdn.net/sunyutian1998/article/details/79618316

query的时候m-ql+1和qr-m写成了m-l+1、r-m,wa了几发之后才找到bug

错误样例:

10 1
Q 5

wrong answer:5

 

顺带一提,这个题目可以在set上面二分直接过,不过最主要还是为了练习区间合并

 

技术分享图片
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e4+5;
struct node
{
    int ll,rr,mm;
} tr[4*maxn];
#define lson o*2
#define rson o*2+1
#define m (l+r)/2
inline void pushup(int o,int l,int r)
{
    tr[o].ll=tr[lson].ll;
    tr[o].rr=tr[rson].rr;
    if(tr[o].ll==m-l+1)
        tr[o].ll+=tr[rson].ll;
    if(tr[o].rr==r-m)
        tr[o].rr+=tr[lson].rr;
    tr[o].mm=max(tr[lson].rr+tr[rson].ll,max(tr[lson].mm,tr[rson].mm));
}
void build(int o,int l,int r)
{
    if(l==r)
    {
        tr[o].ll=tr[o].rr=tr[o].mm=1;
        return;
    }
    build(lson,l,m);
    build(rson,m+1,r);
    pushup(o,l,r);
}
void update(int o,int l,int r,int k,int flag)
{
    if(l==r)
    {
        tr[o].ll=tr[o].rr=tr[o].mm=flag;
        return;
    }
    if(k<=m) update(lson,l,m,k,flag);
    else update(rson,m+1,r,k,flag);
    pushup(o,l,r);
}
int query(int o,int l,int r,int ql,int qr,int flag)
{
    if(ql<=l&&qr>=r)
    {
        if(flag==1) return tr[o].ll;
        else return tr[o].rr;
    }
    if(qr<=m) return query(lson,l,m,ql,qr,flag);
    if(ql>m) return query(rson,m+1,r,ql,qr,flag);
    else
    {
        int pl=query(lson,l,m,ql,qr,flag);
        int pr=query(rson,m+1,r,ql,qr,flag);
        if(flag==1)
        {
            if(pl==m-ql+1) return pl+pr;
            else return pl;
        }
        else
        {
            if(pr==qr-m) return pl+pr;
            else return pr;
        }
    }
}
int a[maxn];
int main()
{
    int n,q;
    while(scanf("%d%d",&n,&q)!=EOF)
    {
        memset(a,0,sizeof a);
        build(1,1,n);
        int tp=0;
        while(q--)
        {
            char s;
            cin>>s;
            if(s==D)
            {
                int x;
                scanf("%d",&x);
                update(1,1,n,x,0);
                a[++tp]=x;
            }
            if(s==Q)
            {
                int x;
                scanf("%d",&x);
                int x1=query(1,1,n,1,x,2);
                int x2=query(1,1,n,x,n,1);
                printf("%d
",x1+x2>0?x1+x2-1:0);
            }
            if(s==R)
            {
                if(tp>=1)
                {
                    int x=a[tp--];
                    update(1,1,n,x,1);
                }
            }
        }
    }
}
View Code

 

以上是关于HDU 1540(线段树+区间合并)学习记录的主要内容,如果未能解决你的问题,请参考以下文章

(i) hdu1540 (区间合并)

HDU1540 Tunnel Warfare —— 线段树 区间合并

HDU 1540 Tunnel Warfare(线段树 区间合并)

HDU 1540 Tunnel Warfare(区间合并)线段树

hdu 1540(线段树区间合并)

hdu--1540 Tunnel Warfare(线段树+区间合并)