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]);
    }
  • 相关阅读:
    Java
    Java
    Java
    Java
    运算问题
    Idea常用快捷键
    java变量和变量命名规范
    java常用数据类型和基本数据类型转换和进制和大数运算
    java注释和标识符规范
    使用命令行生成的第一个java程序
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13429747.html
Copyright © 2011-2022 走看看