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); } } } } }
以上是关于HDU 1540(线段树+区间合并)学习记录的主要内容,如果未能解决你的问题,请参考以下文章
HDU1540 Tunnel Warfare —— 线段树 区间合并
HDU 1540 Tunnel Warfare(线段树 区间合并)