luogu-P1503(fhq treap)

题目背景
小卡正在新家的客厅中看电视。电视里正在播放放了千八百次依旧重播的《亮剑》,剧中李云龙带领的独立团在一个县城遇到了一个鬼子小队,于是独立团与鬼子展开游击战。

题目描述
描述 县城里有n个用地道相连的房子,第i个只与第i-1和第i+1个相连。这是有m个消息依次传来

1、消息为D x:鬼子将x号房子摧毁了,地道被堵上。

2、消息为R :村民们将鬼子上一个摧毁的房子修复了。

3、消息为Q x:有一名士兵被围堵在x号房子中。

李云龙收到信息很紧张,他想知道每一个被围堵的士兵能够到达的房子有几个。

输入格式
第一行2个整数n,m(n,m<=50000)。

接下来m行,有如题目所说的三种信息共m条。

输出格式
对于每一个被围堵的士兵,输出该士兵能够到达的房子数。

输入
输入

7 9
D 3
D 6
D 5
Q 4
Q 5
R
Q 4
R
Q 4

输出

1
0
2
4

说明/提示
若士兵被围堵在摧毁了的房子中,那只能等死了。。。。。。

这道题我们可以将每一个摧毁的村庄编号加入平衡树中,然后我们在询问时,找到询问的编号的前驱和后继就可以啦,如果这个村庄已经被删除了,那么就可以直接输出0,因为提示[雾]。
代码:

#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 7;
std::mt19937 rnd(233);
struct treap
{
    int l, r, size, val, key;
}t[maxn];
int cnt, root;
inline int newnode(int val)
{
    t[++cnt] = treap{0, 0, 1, val, rnd()};
    return cnt;
}
inline void update(int now)
{
    t[now].size = t[t[now].l].size + t[t[now].r].size + 1;
}
inline void split(int now,int val,int &x,int &y)
{
    if(!now){
        x = y = 0;
        return;
    }
    if(t[now].val<=val){
        x = now;
        split(t[now].r, val, t[now].r, y);
    }
    else{
        y = now;
        split(t[now].l, val, x, t[now].l);
    }
    update(now);
}
inline int merge(int x,int y)
{
    if(!x||!y)
        return x + y;
    if(t[x].key>t[y].key){
        t[x].r = merge(t[x].r, y);
        update(x);
        return x;
    }
    else{
        t[y].l = merge(x, t[y].l);
        update(y);
        return y;
    }
}
int x, y, z;
inline void insert(int val)
{
    split(root, val, x, y);
    root = merge(merge(x, newnode(val)), y);
}
inline void del(int val)
{
    split(root, val, x, z);
    split(x, val - 1, x, y);
    y = merge(t[y].l, t[y].r);
    root = merge(merge(x, y), z);
}
inline int pre(int val)
{
    split(root, val, x, y);
    int now = x;
    while(t[now].r){
        now = t[now].r;
    }
    root = merge(x, y);
    return t[now].val;
}
inline int nex(int val)
{
    split(root, val, x, y);
    int now = y;
    while(t[now].l){
        now = t[now].l;
    }
    root = merge(x, y);
    return t[now].val;
}
inline void read(int &val)
{
    val = 0;
    int f = 1;
    char c = getchar();
    while(c<'0' || c>'9'){
        if(c=='-')
            f = -1;
        c = getchar();
    }
    while(c<='9' && c>='0'){
        val = val * 10 + c - '0';
        c = getchar();
    }
    val *= f;
}
char s[2];
int st[maxn], top, vis[maxn];
int main()
{
    int n, m;
    read(n), read(m);
    insert(0), insert(n + 1);
    while(m--){
        scanf("%s", s);
        int num;
        if(s[0]=='D'){
            read(num);
            insert(num);
            vis[num] = 1;
            st[++top] = num;
        }
        else if(s[0]=='R'){
            del(st[top]);
            vis[st[top]] = 0;
            top--;
        }
        else{
            read(num);
            if(vis[num]){
                cout << 0 << endl;
                continue;
            }
            int l = pre(num), r = nex(num);
            cout << r - l - 1 << endl;
        }
    }
}
发布了34 篇原创文章 · 获赞 3 · 访问量 234

猜你喜欢

转载自blog.csdn.net/qq_44641782/article/details/103686641