zoukankan      html  css  js  c++  java
  • P1503 鬼子进村(Treap树)

    题意:

    县城里有 nn 个用地道相连的房子,第 ii 个只与第 i-1i1 和第 i+1i+1 个相连。这时有 mm 个消息依次传来:

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

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

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

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

    题解:

    对每个D操作和R操作,就是在平衡树上做插入和删除,对Q操作就是在平衡树上查询前驱和后继,做差就是答案。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+100;
    const int inf=1e9;
    int n,m;
    int a[maxn];
    struct Treap_tree {
        int ch[2];
        int v;
        int dat;//优先级 
        int size;//子树节点数 
        int cnt;//重复数 
    }t[maxn];
    int tot;
    int root;
    int newNode (int v) {
        tot++;
        t[tot].v=v;
        t[tot].dat=rand();//随机优先级
        t[tot].size=1;
        t[tot].cnt=1;
        return tot; 
    } 
    void pushup (int x) {
        t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
    }
    void build () {
        
    }
    void rotate (int &id,int d) {
        int tt=t[id].ch[d^1];
        t[id].ch[d^1]=t[tt].ch[d];
        t[tt].ch[d]=id;
        id=tt;
        pushup(t[id].ch[d]);
        pushup(id);
    }
    void ins (int &id,int v) {
        if (!id) {
            id=newNode(v);
            return;
        }
        if (v==t[id].v) t[id].cnt++;
        else {
            ins(t[id].ch[v>t[id].v],v);
            if (t[id].dat<t[t[id].ch[v>t[id].v]].dat) rotate(id,v<t[id].v);
        }
        pushup(id);
    }
    void remove (int &id,int v) {
        if (!id) return;
        if (v==t[id].v) {
            if (t[id].cnt>1) {
                t[id].cnt--;
                pushup(id);
                return;
            }
            if (t[id].ch[0]||t[id].ch[1]) {
                if (!t[id].ch[1]||t[t[id].ch[0]].dat>t[t[id].ch[1]].dat) {
                    rotate(id,1);
                    remove(t[id].ch[1],v);
                }
                else {
                    rotate(id,0);
                    remove(t[id].ch[0],v);
                }
                pushup(id);
            }
            else
                id=0;
            return;
        }
        remove(t[id].ch[v>t[id].v],v);
        pushup(id);
    }
    int rk (int id,int v) {
        if (!id) return 0;
        if (v==t[id].v) 
            return t[t[id].ch[0]].size+1;
        else if (v<t[id].v)
            return rk(t[id].ch[0],v);
        else
            return t[t[id].ch[0]].size+t[id].cnt+rk(t[id].ch[1],v);
    }
    int kth (int id,int k) {
        if (!id) return inf;
        if (k<=t[t[id].ch[0]].size)
            return kth(t[id].ch[0],k);
        else if (k<=t[t[id].ch[0]].size+t[id].cnt)
            return t[id].v;
        else
            return kth(t[id].ch[1],k-t[t[id].ch[0]].size-t[id].cnt);
    }
    int get_pre (int id,int v) {
        int pre;
        while (id) {
            if (t[id].v<v)
                pre=t[id].v,id=t[id].ch[1];
            else
                id=t[id].ch[0];
        }
        return pre;
    }
    int get_next (int id,int v) {
        int nxt;
        while (id) {
            if (t[id].v>v)
                nxt=t[id].v,id=t[id].ch[0];
            else
                id=t[id].ch[1];
        }
        return nxt;
    }
    
    
    int main () {
        scanf("%d%d",&n,&m);
        vector<int> ans;
        stack<int> pre;
        ins(root,0);
        ins(root,n+1);
        for (int i=1;i<=m;i++) {
            string s;
            int x;
            cin>>s;
            if (s=="D")  
                scanf("%d",&x),a[x]=1,ins(root,x),pre.push(x);
            if (s=="R")
                a[pre.top()]=0,remove(root,pre.top()),pre.pop();
            if (s=="Q") {
                scanf("%d",&x);
                if (a[x]==1) {
                    ans.push_back(0);
                    continue;
                }
                int l=get_pre(root,x);
                int r=get_next(root,x);
                ans.push_back(r-l-1);
            }
        }
        for (int i=0;i<ans.size();i++) printf("%d
    ",ans[i]);
    }
  • 相关阅读:
    [HNOI2002]营业额统计
    HDU 1374
    HDU 3345
    HDU 2089
    Graham扫描法
    Codeforces 1144D Deduction Queries 并查集
    Codeforces 916E Jamie and Tree 线段树
    Codeforces 1167F Scalar Queries 树状数组
    Codeforces 1167E Range Deleting
    Codeforces 749E Inversions After Shuffle 树状数组 + 数学期望
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13429747.html
Copyright © 2011-2022 走看看