抗日戦争中、大規模なトンネル戦の華北平原の広大な地域。一般に、一列に接続された村のトンネル経由。両端部に加えて、それぞれが直接村に隣接する2つの村に接続されています。
侵入者の攻撃は、多くの場合、いくつかの村のために、それらのトンネルの一部を破壊しました。八路軍司令官と最新のトンネル接続状態の村の要件。いくつかの村厳しく分離した場合は、すぐに接続を復元する必要があります!
入力
最初の入力ラインは2つの正の整数nとm(nは、m≤50,000)を備え、それはイベントや村の数を表します。第m行の各行は、次のイベントを記述する。
以下に示す異なるフォーマットは、3つの異なるイベントを記述する:
D X:X-村が破壊されました。
Q X:直接的または間接的にそれに関連したXコマンダー問い合わせ番号村村。
R:村の最終破壊は再建されました。
出力
問い合わせへの注文の答えの各指揮官の出力。
サンプル入力
7 9
D 3
D 6
D 5
Q 4
、Q 5
R
Q 4
のR
Q 4
サンプル出力
1
0
2
4つの。
分析:
各ノードに対応するメンテナンス間隔は、右列、最長間隔の列まで1の最長の文字列を、左。現在のクエリの時間間隔0またはフル1の最大ランレングス場合は、直接フル\ 0を返し、xは現在のセクション「中央」(共に接続左の子の左右と右の子供)であれば、中央リターンの長さは、直接;加えて、検索を継続します。
コード:
1 #include <bits/stdc++.h>//题目也没说多组输入啊,WA了好多次,想哭 2 using namespace std; 3 const int maxn = 5 * 1e4 + 10; 4 struct node 5 { 6 int l, r; 7 int ln, rn, mn; 8 }t[maxn << 2]; 9 10 int n, m; 11 12 void pushup(int tar) 13 { 14 t[tar].ln = t[tar << 1].ln, t[tar].rn = t[tar << 1 | 1].rn; 15 t[tar].mn = max(t[tar << 1].mn, t[tar << 1 | 1].mn); 16 t[tar].mn = max(t[tar].mn, t[tar << 1].rn + t[tar << 1 | 1].ln); 17 if (t[tar << 1].ln == t[tar << 1].r - t[tar << 1].l + 1) t[tar].ln = t[tar << 1].ln + t[tar << 1 | 1].ln; 18 if (t[tar << 1 | 1].rn == t[tar << 1 | 1].r - t[tar << 1 | 1].l + 1) t[tar].rn = t[tar << 1 | 1].rn + t[tar << 1].rn; 19 } 20 21 void build(int l, int r, int tar) 22 { 23 t[tar].l = l, t[tar].r = r; 24 t[tar].ln = t[tar].rn = t[tar].mn = r - l + 1; 25 if (l == r) return; 26 int mid = (l + r) >> 1; 27 build(l, mid, tar << 1); 28 build(mid + 1, r, tar << 1 | 1); 29 } 30 31 void update(int x, int state, int tar) 32 { 33 if (t[tar].l == t[tar].r) 34 { 35 t[tar].ln = t[tar].rn = t[tar].mn = state; 36 return; 37 } 38 int mid = (t[tar].l + t[tar].r) >> 1; 39 if (x <= mid) update(x, state, tar << 1); 40 else if (x > mid) update(x, state, tar << 1 | 1); 41 pushup(tar); 42 } 43 44 int query(int x, int tar) 45 { 46 if (t[tar].mn == 0 || t[tar].mn == t[tar].r - t[tar].l + 1) 47 return t[tar].mn; 48 int mid = (t[tar].l + t[tar].r) >> 1; 49 if (x >= t[tar << 1].r - t[tar << 1].rn + 1 && x <= t[tar << 1 | 1].l + t[tar << 1 | 1].ln - 1) return t[tar << 1].rn + t[tar << 1 | 1].ln; 50 else if (x <= mid) return query(x, tar << 1); 51 else return query(x, tar << 1 | 1); 52 } 53 54 int main() 55 { 56 int n, m; 57 58 while (cin >> n >> m) 59 { 60 stack<int> s; 61 char ope[2]; 62 int x; 63 64 build(1, n, 1); 65 while (m--) 66 { 67 cin >> ope; 68 if (ope[0] == 'D') 69 { 70 cin >> x; 71 s.push(x); 72 update(x, 0, 1); 73 } 74 else if (ope[0] == 'R') 75 { 76 x = s.top(); 77 s.pop(); 78 update(x, 1, 1); 79 } 80 else 81 { 82 cin >> x; 83 cout << query(x, 1) << endl; 84 } 85 } 86 } 87 }