羅区P1503の強盗
説明
ランド家に接続されたnチャネルの記述郡、i番目のI-1〜I + 1番目のみに接続されています。これは、メッセージシーケンスがmに来ています
図1に示すように、メッセージDのX:X悪魔自宅番号、ブロックされたトンネルを破壊します。
2、Rへのメッセージ:破壊された家屋の修理デビルズに村。
3、メッセージQは、X:兵士は数x封じ込め家にありました。
李雲龍は非常に神経質な情報を受信、彼はすべての家を知りたかったの封じ込め兵士は数に到達することができます。
入力
最初の二つの整数のラインN、M(N、M <= 50000)。
続いて行、Mの前記合計のタイトルのような情報の3種類のMです。
出力
- 兵士の封じ込めのそれぞれについて、兵士の家屋番号の出力が到達することができます。
サンプル入力
7 9 D 3 D 6 D 5 Q 4 Q 5 R Q 4 R Q 4
サンプル出力
1
0
2
4
ソリューション:
- バランスのとれたツリー。
- 最後に、問題のテンプレートの範囲外。あなたが考える場合はバランスの取れたツリーの考えと、この問題は考えることは容易です。Treapは家のメンテナンス位置を破壊し、Dが動作位置に挿入されると、(現在の位置xに設定)Q操作が答えは( - Xの前身--1 Xの後継)です。R動作が質問の意味に従ってスタックをシミュレートすることができます取得します。
- またはWord、賢いと後継機能にバランスの取れた木の前身!
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <stack>
#define N 50005
using namespace std;
struct T {int l, r, val, dat;} t[N];
int n, m, root, tot;
stack<int> stk;
int read()
{
int x = 0; char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x;
}
int New(int val)
{
t[++tot].val = val;
t[tot].dat = rand();
return tot;
}
void zig(int &y)
{
int x = t[y].l;
t[y].l = t[x].r, t[x].r = y, y = x;
}
void zag(int &x)
{
int y = t[x].r;
t[x].r = t[y].l, t[y].l = x, x = y;
}
void insert(int &p, int val)
{
if(!p) {p = New(val); return;}
if(val == t[p].val) return;
if(val < t[p].val)
{
insert(t[p].l, val);
if(t[t[p].l].dat > t[p].dat) zig(p);
}
else
{
insert(t[p].r, val);
if(t[t[p].r].dat > t[p].dat) zag(p);
}
}
void erase(int &p, int val)
{
if(!p) return;
if(val == t[p].val)
{
if(t[p].l || t[p].r)
{
if(!t[p].r || t[t[p].l].dat > t[p].dat) zig(p), erase(t[p].r, val);
else zag(p), erase(t[p].l, val);
}
else p = 0;
return;
}
val < t[p].val ? erase(t[p].l, val) : erase(t[p].r, val);
}
int preNext(int op, int val)
{
int ans = op == 0 ? 2 : 1, p = root;
while(p)
{
if(val == t[p].val)
{
if(!op && t[p].l)
{
p = t[p].l;
while(t[p].r) p = t[p].r;
ans = p; break;
}
else if(!op) break;
if(op && t[p].r)
{
p = t[p].r;
while(t[p].l) p = t[p].l;
ans = p; break;
}
else if(op) break;
}
if(!op && t[p].val < val && t[p].val > t[ans].val) ans = p;
if(op && t[p].val > val && t[p].val < t[ans].val) ans = p;
p = val < t[p].val ? t[p].l : t[p].r;
}
return t[ans].val;
}
bool find(int p, int val)
{
if(!p) return 0;
if(val == t[p].val) return 1;
if(val < t[p].val) return find(t[p].l, val);
else return find(t[p].r, val);
}
int main()
{
cin >> n >> m;
New(n + 1), New(0), root = 1, t[1].l = 2;
for(int i = 1; i <= m; i++)
{
char c[2]; scanf("%s", c);
if(c[0] == 'D')
{
int x = read();
insert(root, x);
stk.push(x);
}
else if(c[0] == 'R')
{
erase(root, stk.top());
stk.pop();
}
else if(c[0] == 'Q')
{
int x = read();
if(find(root, x)) printf("0\n");
else printf("%d\n", preNext(1, x) - preNext(0, x) - 1);
}
}
return 0;
}