1. 程式人生 > >HDU 1540(線段樹+區間合並)學習記錄

HDU 1540(線段樹+區間合並)學習記錄

div uil hdu 1540 hup fin bsp play names http

學習了線段樹的新姿勢,記錄一下

參考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\n",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(線段樹+區間合並)學習記錄