HDU 1540(線段樹+區間合併)學習記錄
阿新 • • 發佈:2018-11-19
學習了線段樹的新姿勢,記錄一下
參考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
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=5e4+5; 4 struct node 5 { 6 int ll,rr,mm;View Code7 } tr[4*maxn]; 8 #define lson o*2 9 #define rson o*2+1 10 #define m (l+r)/2 11 inline void pushup(int o,int l,int r) 12 { 13 tr[o].ll=tr[lson].ll; 14 tr[o].rr=tr[rson].rr; 15 if(tr[o].ll==m-l+1) 16 tr[o].ll+=tr[rson].ll; 17 if(tr[o].rr==r-m) 18 tr[o].rr+=tr[lson].rr;19 tr[o].mm=max(tr[lson].rr+tr[rson].ll,max(tr[lson].mm,tr[rson].mm)); 20 } 21 void build(int o,int l,int r) 22 { 23 if(l==r) 24 { 25 tr[o].ll=tr[o].rr=tr[o].mm=1; 26 return; 27 } 28 build(lson,l,m); 29 build(rson,m+1,r); 30 pushup(o,l,r);31 } 32 void update(int o,int l,int r,int k,int flag) 33 { 34 if(l==r) 35 { 36 tr[o].ll=tr[o].rr=tr[o].mm=flag; 37 return; 38 } 39 if(k<=m) update(lson,l,m,k,flag); 40 else update(rson,m+1,r,k,flag); 41 pushup(o,l,r); 42 } 43 int query(int o,int l,int r,int ql,int qr,int flag) 44 { 45 if(ql<=l&&qr>=r) 46 { 47 if(flag==1) return tr[o].ll; 48 else return tr[o].rr; 49 } 50 if(qr<=m) return query(lson,l,m,ql,qr,flag); 51 if(ql>m) return query(rson,m+1,r,ql,qr,flag); 52 else 53 { 54 int pl=query(lson,l,m,ql,qr,flag); 55 int pr=query(rson,m+1,r,ql,qr,flag); 56 if(flag==1) 57 { 58 if(pl==m-ql+1) return pl+pr; 59 else return pl; 60 } 61 else 62 { 63 if(pr==qr-m) return pl+pr; 64 else return pr; 65 } 66 } 67 } 68 int a[maxn]; 69 int main() 70 { 71 int n,q; 72 while(scanf("%d%d",&n,&q)!=EOF) 73 { 74 memset(a,0,sizeof a); 75 build(1,1,n); 76 int tp=0; 77 while(q--) 78 { 79 char s; 80 getchar(); 81 scanf("%c",&s); 82 if(s=='D') 83 { 84 int x; 85 scanf("%d",&x); 86 update(1,1,n,x,0); 87 a[++tp]=x; 88 } 89 if(s=='Q') 90 { 91 int x; 92 scanf("%d",&x); 93 int x1=query(1,1,n,1,x,2); 94 int x2=query(1,1,n,x,n,1); 95 printf("%d\n",x1+x2>0?x1+x2-1:0); 96 } 97 if(s=='R') 98 { 99 if(tp>=1) 100 { 101 int x=a[tp--]; 102 update(1,1,n,x,1); 103 } 104 } 105 } 106 } 107 } 108 /* 109 10 1 110 Q 5 111 */
順帶一提,這個題目可以在set上面二分直接過,程式碼如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int a[50005]; 4 int main() 5 { 6 int n,q; 7 while(~scanf("%d%d",&n,&q)) 8 { 9 set<int>st; 10 st.insert(0); 11 int tp=0; 12 while(q--) 13 { 14 char c; 15 getchar(); 16 scanf("%c",&c); 17 if(c=='D') 18 { 19 int x; 20 scanf("%d",&x); 21 st.insert(x); 22 a[++tp]=x; 23 } 24 if(c=='Q') 25 { 26 int x; 27 scanf("%d",&x); 28 set<int>::iterator iter=st.lower_bound(x); 29 if(iter==st.end()) 30 { 31 iter--; 32 printf("%d\n",n-*iter); 33 } 34 else 35 { 36 if(*iter==x) puts("0"); 37 else 38 { 39 int tmp=*iter; 40 iter--; 41 printf("%d\n",tmp-*iter-1); 42 } 43 } 44 } 45 if(c=='R') 46 { 47 if(tp>=1) 48 { 49 int x=a[tp--]; 50 st.erase(x); 51 } 52 } 53 } 54 } 55 }View Code