hdu1540-Tunnel Warfare- (half segment tree +)

The meaning of problems: there are n villages in a row, may communicate with neighboring villages, the communication can not blow up, operations performed m. 3 modes of operation, 1 to blow up a village; 2 on repair a bombed village; 3 queries a village several villages can communicate (do the math a).

Problem solving: seeking a left and right of the point spread and the spread range, not even 1 was blown up, blow up the count 0 and look left and right boundaries by half, assuming the query point is x, then x is a left border -l + 1 = query (), is a right boundary criterion r-x + 1 = query (); two half log, query is the query log, the time complexity is O (n + m * log * log), limit speed 2000ms, 1600 + ms, the idea is simple, barely able to live.

There is also a pit: a village can be repeatedly blown up, repair just once is enough.

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<math.h>
  6 #include<string>
  7 #include<map>
  8 #include<queue>
  9 #include<stack>
 10 #include<set>
 11 #define ll long long
 12 #define inf 0x3f3f3f3f
 13 using namespace std;
 14 
 15 int n,m;
50005a [int16 ];
 17 int sum[50005*4];
 18 stack<int>sta;
 19 
 20 void build(int l,int r,int rt)
 21 {
 22     if(l==r)
 23     {
 24         sum[rt]=a[l];
 25         return;
 26     }
 27     int mid=(l+r)/2;
 28     build(l,mid,rt*2);
 29     Build (MID + . 1 , R & lt, RT * 2 + . 1 );
 30  
31 is      SUM [RT] = SUM [RT * 2 ] + SUM [RT * 2 + . 1 ];
 32  }
 33 is  
34 is  void Update ( int P, int C, int L, int R & lt, int RT)
 35  {
 36      IF (R & lt == L) /// leaf node is reached, returns the modified 
37 [      {
 38 is          SUM [RT] = SUM [RT] + C;
 39          return ;
 40      }
41 is      int MID = (L + R & lt) / 2 ;
 42 is      /// left or right is determined according to the conditions call 
43 is      IF (P <= MID) Update (P, C, L, MID, RT * 2 );
 44 is      the else      Update (P, C, MID + . 1 , R & lt, RT * 2 + . 1 );
 45      SUM [RT] = SUM [RT * 2 ] + SUM [RT * 2 + . 1 ];
 46 is  }
 47  
48  int Query ( int L, int R & lt, int L, int R & lt, int RT)
 49  {
50      IF (L <= R & lt && L <= R & lt) /// in the interval, the direct return 
51 is          return SUM [RT];
 52 is  
53 is      int m = (L + R & lt) / 2 ;
 54 is  
55      /// cumulative answer 
56 is      int ANS = 0 ;
 57 is      IF (L <= m) ANS = ANS + Query (L, R & lt, L, m, RT * 2 );
 58      IF (R & lt> m) ANS = ANS + Query (L, R & lt, m + . 1 , R & lt, RT * 2 + . 1 );
 59  
60      return ANS;
 61 is  }
 62 is  
63 is  int main ()
 64 {
 65     while(scanf("%d%d",&n,&m)!=EOF)
 66     {
 67         while(!sta.empty())
 68             sta.pop();
 69         set<int>se;
 70         for(int i=1;i<=n;i++)
 71             a[i]=1;
 72         build(1,n,1);
 73         char c;
 74         while(m--)
 75         {
 76             getchar();
 77             scanf("%c",&c);
 78             int x;
 79             if(c=='D')
 80             {
 81                 scanf("%d",&x);
 82                 if(a[x]!=0)
 83                     update(x,-1,1,n,1);
 84                 a[x]=0;
 85                 sta.push(x);
 86             }
 87             else if(c=='R')
 88             {
 89                 x=sta.top();
 90                 if( a[x]==0 );
 91                 else
 92                 {
 93                     while( a[x]!=0 )
 94                     {
 95                         sta.pop();
 96                         x = sta.top();
 97                     }
 98                 }
 99                 sta.pop();
100                 a[x]=1;
101                 update(x,1,1,n,1);
102             }
103             else
104             {
105                 int ans=0;
106                 scanf("%d",&x);
107 
108                 if(a[x]!=0)
109                 {
110                     int l=1, R & lt = X, RES1 = - . 1 , RES2 = - . 1 ;
 111                      the while (L <= R & lt) /// left to find the maximum number of communication village 
112                      {
 113                          int MID = (L + R & lt) / 2 ;
 114                          IF (Query (MID, X, . 1 , n-, . 1 ) == + MID-X . 1 ) /// fair share two left looking MID 
115                          {
 1 16                              RES1 = MID;
 117                              R & lt mid- = . 1 ;
 1 18  
119                          }
 120                          the else // / two fair shareRight to find 
121                          {
 122                              L = MID + . 1 ;
 123                          }
 124                      }
 125                      L = X, R & lt = n-;
 126                      the while (L <= R & lt)
 127                      {
 128                          int MID = (L + R & lt) / 2 ;
 129  
130.                          IF ( Query (X, MID, . 1 , n-, . 1 ) == + MID-X . 1 )
 131 is                          {
 132                              RES2 = MID;
133                             l=mid+1;
134                         }
135                         else
136                             r=mid-1;
137                     }
138                     printf("%d\n",res2-res1+1);
139                 }
140                 else
141                     printf("0\n");
142             }
143         }
144 
145     }
146 
147     return 0;
148 }
149 /**
150 5 12
151 D 3
152 D 2
153 D 1
154 D 1
155 D 2
156 R
157 R
158 R
159 Q 1
160 Q 2
161 Q 3
162 Q 4
163 */

 

Guess you like

Origin www.cnblogs.com/shoulinniao/p/11206632.html