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

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

 

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 const int maxn=5e4+5;
  4 struct node
  5 {
  6     int ll,rr,mm;
7 } 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 */
View Code

 

順帶一提,這個題目可以在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