zoukankan      html  css  js  c++  java
  • P2286 [HNOI2004]宠物收养场

    P2286 [HNOI2004]宠物收养场

    splay

    我们只需要一棵splay

    如果有宠物剩下,那么此时就是宠物树。领走的时候查找并删去树内元素,反之亦然。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<cmath>
    #define re register
    using namespace std;
    template <typename T> inline T min(T &a,T &b) {return a<b ?a:b;}
    template <typename T> inline T max(T &a,T &b) {return a>b ?a:b;}
    template <typename T> inline void read(T &x){
        char c=getchar(); x=0; bool f=1;
        while(!isdigit(c)) f= !f||c=='-' ? 0:1,c=getchar();
        while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
        x= f ? x:-x;
    }
    template <typename T> inline void output(T x){
        if(!x) {putchar(48); return ;}
        if(x<0) putchar('-'),x=-x;
        int wt[50],l=0;
        while(x) wt[++l]=x%10,x/=10;
        while(l) putchar(wt[l--]+48);
    }
    const int mod=1e6;
    struct data{int fa,ch[2],v;}a[200002];
    int n,u,rt;
    inline void rte(int x,int &k){
        int y=a[x].fa,z=a[y].fa;
        int l=(a[y].ch[1]==x),r=l^1;
        if(y==k) k=x;
        else a[z].ch[a[z].ch[1]==y]=x;
        a[x].fa=z,a[a[x].ch[r]].fa=y,a[y].fa=x;
        a[y].ch[l]=a[x].ch[r],a[x].ch[r]=y;
    }
    inline void splay(int x,int &k){
        for(;x!=k;rte(x,k)){
            int y=a[x].fa,z=a[y].fa;
            if(y!=k){
                if((a[y].ch[0]==x)^(a[z].ch[0]==y)) rte(x,k);
                else rte(y,k);
            }
        }
    }
    //-----模板------ inline
    void ins(int x){ int p=rt,_fa=0; while(p&&a[p].v!=x) _fa=p,p=a[p].ch[a[p].v<x]; if(!p){ p=++u,a[p].fa=_fa,a[p].v=x; if(_fa) a[_fa].ch[a[_fa].v<x]=p; }splay(p,rt);//把新插的点旋到根上,跑得飞快 } inline void find(int x){ //找到元素x在树中的位置并旋到根上 int p=rt; if(!p) return ; while(a[p].ch[a[p].v<x]&&a[p].v!=x) p=a[p].ch[a[p].v<x]; splay(p,rt); } inline int Nxt(int x,int k){ //不严格前驱/后继(可以等于) find(x); int p=rt; if(a[p].v>=x&&k) return p; if(a[p].v<=x&&!k) return p; p=a[p].ch[k]; while(a[p].ch[k^1]) p=a[p].ch[k^1]; return p; } inline int Nxt_une(int x,int k){//严格前驱/后继 find(x); int p=rt; if(a[p].v>x&&k) return p; if(a[p].v<x&&!k) return p; p=a[p].ch[k]; while(a[p].ch[k^1]) p=a[p].ch[k^1]; return p; } inline void remov(int x){ //删除 int p1=Nxt_une(x,0); int p2=Nxt_une(x,1); //找出严格前驱/后继,并旋到根上 splay(p1,rt); splay(p2,a[p1].ch[1]); a[p2].ch[0]=0; } int main(){ read(n); int q1,q2,cnt=0; long long ans=0; ins(-2e8); ins(2e8); for(re int i=1;i<=n;++i){ read(q1),read(q2); if(cnt==0) ins(q2); //空树直接加 else if(cnt>0){ //两种情况 if(q1) ins(q2); else{ int p1=a[Nxt(q2,0)].v; int p2=a[Nxt(q2,1)].v; if(abs(q2-p1)<=abs(p2-q2)) remov(p1),ans+=abs(q2-p1); else remov(p2),ans+=abs(p2-q2); } }else{ if(!q1) ins(q2); else{ int p1=a[Nxt(q2,0)].v; int p2=a[Nxt(q2,1)].v; if(abs(q2-p1)<=abs(p2-q2)) remov(p1),ans+=abs(q2-p1); else remov(p2),ans+=abs(p2-q2); } } cnt+= q1 ? 1:-1; ans%=mod; }printf("%lld",ans); return 0; }
  • 相关阅读:
    二维数组 A[m][n] 按行优先和按列优先的 下标地址转换公式
    服务器的公网ip 和内网ip
    剑指offer 23.二叉搜索树的后序遍历序列
    剑指offer 22. 从上往下打印二叉树 & 102. 二叉树的层序遍历
    剑指offer 21.栈的压入、弹出序列 & leetcode 剑指 Offer 31. 栈的压入、弹出序列
    剑指offer 4. 重建二叉树 & leetcode 剑指 Offer 07. 重建二叉树 & leetcode hot 100 105. 从前序与中序遍历序列构造二叉树
    Linux配置Nginx+Tomcat负载均衡
    yum安装apache及问题解决
    Linux高级文本处理命令
    JMeter:生成漂亮的多维度的HTML报告
  • 原文地址:https://www.cnblogs.com/kafuuchino/p/9727167.html
Copyright © 2011-2022 走看看