zoukankan      html  css  js  c++  java
  • HNOI2017单旋

    单旋
    • 这道题做法贼多,LCT,splay,线段树什么的貌似都行。
    • 像我这种渣渣只会线段树了(高级数据结构学了也不会用)。
    • 首先离线所有操作,因为不会有两个点值重复,所以直接离散。
    • 一颗线段树来维护所有点的深度,并将所有值丢进(set)中。
    • 插入操作,在set找到前驱后继,前驱没有右儿子就放前驱右儿子,否则放后继左儿子,同时用(ch)(fa)假装模拟树的形态。
    • 旋转操作,在(set)里找到节点,可以发现旋转操作该点儿子深度不变,其他点深度加一,处理一下父子关系,然后线段树修改区间即可。
    • 删除操作,先旋转操作,(root)一定只有一个儿子,直接删掉(root)即可,将所有点深度减一
    // luogu-judger-enable-o2
    #include<bits/stdc++.h>
    using namespace std;
    typedef int sign;
    typedef long long ll;
    #define For(i,a,b) for(register sign i=(sign)a;i<=(sign)b;++i)
    #define Fordown(i,a,b) for(register sign i=(sign)a;i>=(sign)b;--i)
    const int N=1e5+5;
    bool cmax(sign &a,sign b){return (a<b)?a=b,1:0;}
    bool cmin(sign &a,sign b){return (a>b)?a=b,1:0;}
    template<typename T>inline T read()
    {
        T f=1,ans=0;
        char ch=getchar();
        while(!isdigit(ch)&&ch!='-')ch=getchar();
        if(ch=='-')f=-1,ch=getchar();
        while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
        return ans*f;
    }
    template<typename T>inline void write(T x,char y)
    {
        if(x==0)
        {
            putchar('0');putchar(y);
            return;
        }
        if(x<0)
        {
            putchar('-');
            x=-x;
        }
        static char wr[20];
        int top=0;
        for(;x;x/=10)wr[++top]=x%10+'0';
        while(top)putchar(wr[top--]);
        putchar(y);
    }
    void file()
    {
        #ifndef ONLINE_JUDGE
            freopen("3721.in","r",stdin);
            freopen("3721.out","w",stdout);
        #endif
    }
    int n,opt[N][2];
    int a[N],top;
    void input()
    {
        n=read<int>();
        For(i,1,n)
        {
            opt[i][0]=read<int>();
            if(opt[i][0]==1)a[++top]=read<int>(),opt[i][1]=a[top];
        }
    }
    namespace Tree
    {
        #define mid ((l+r)>>1)
        #define lson h<<1,l,mid
        #define rson h<<1|1,mid+1,r
        ll lazy[N<<2],sum[N<<2];
        void push_down(int h,int l,int r)
        {
            if(!lazy[h])return;
            int ls=h<<1,rs=ls|1;
            lazy[ls]+=lazy[h];lazy[rs]+=lazy[h];
            sum[ls]+=lazy[h]*1ll*(mid-l+1);
            sum[rs]+=lazy[h]*1ll*(r-mid);
            lazy[h]=0;
        }
        void push_up(int h)
        {
            sum[h]=sum[h<<1]+sum[h<<1|1];
        }
        void update(int h,int l,int r,int s,int t,int v)
        {
            if(s<=l&&r<=t)
            {
                lazy[h]+=v;
                sum[h]+=1ll*v*1ll*(r-l+1);
            }
            else
            {
                push_down(h,l,r);
                if(s<=mid)update(lson,s,t,v);
                if(mid<t)update(rson,s,t,v);
                push_up(h);
            }
        }
        int query(int h,int l,int r,int pos)
        {
            if(l==r)return sum[h];
            push_down(h,l,r);
            int res;
            if(pos<=mid)res=query(lson,pos);
            else res=query(rson,pos);
            push_up(h);
            return res;
        }
        void modify(int h,int l,int r,int pos,int v)
        {
            if(l==r)sum[h]=v;
            else
            {
                push_down(h,l,r);
                if(pos<=mid)modify(lson,pos,v);
                else modify(rson,pos,v);
                push_up(h);
            }
        }
    }
    set<int>s;
    set<int>::iterator it;
    int root,ch[N][2],fa[N];
    typedef pair<int,int>pii;
    #define fir first
    #define sec second
    void insert(int x)
    {
        int pre,predep;
        it=s.insert(x).fir;
        if(!root)
        {
            root=x;
            Tree::modify(1,1,n,x,1);
            puts("1");
            return;
        }
        if(it==s.begin())
        {
            ++it;pre=*it;
            fa[x]=pre;ch[pre][0]=x;
        }
        else
        {
            --it;
            if(!ch[*it][1])
            {
                pre=*it;
                fa[x]=pre;
                ch[pre][1]=x;
            }
            else
            {
                ++it;++it;
                pre=*it;
                fa[x]=pre;
                ch[pre][0]=x;
            }
        }
        predep=Tree::query(1,1,n,pre);
        write(predep+1,'
    ');
        Tree::modify(1,1,n,x,predep+1);
    }
    void clear(int x)
    {
        ch[x][0]=ch[x][1]=fa[x]=0;
    }
    void rotate_min()
    {
        it=s.begin();
        int x=*it;
        if(x==root){puts("1");return;}
        int y=ch[x][1],oldroot=root,pre=fa[x];
        write(Tree::query(1,1,n,x),'
    ');
        if(y)Tree::update(1,1,n,x+1,fa[x]-1,-1);
        Tree::update(1,1,n,1,n,1);
        Tree::modify(1,1,n,x,1);
        root=x;
        ch[x][1]=oldroot;fa[oldroot]=x;
        ch[pre][0]=y;fa[y]=pre;
    }
    void del_min()
    {
        rotate_min();
        s.erase(root);
        Tree::update(1,1,n,1,n,-1);
        if(!ch[root][0]&&!ch[root][1])clear(root),root=0;
        else
        {
            int oldroot=root;
            root=ch[root][1];
            clear(oldroot);fa[root]=0;
        }
    }
    void rotate_max()
    {
        it=s.end();--it;
        int x=*it;
        if(x==root){puts("1");return;}
        write(Tree::query(1,1,n,x),'
    ');
        int y=ch[x][0],oldroot=root,pre=fa[x];
        if(y)Tree::update(1,1,n,fa[x]+1,x-1,-1);
        Tree::update(1,1,n,1,n,1);
        Tree::modify(1,1,n,x,1);
        root=x;
        fa[oldroot]=x;ch[x][0]=oldroot;
        ch[pre][1]=y;fa[y]=pre;
    }
    void del_max()
    {
        rotate_max();
        s.erase(root);
        Tree::update(1,1,n,1,n,-1);
        if(!ch[root][0]&&!ch[root][1])clear(root),root=0;
        else
        {
            int oldroot=root;
            root=ch[root][0];
            clear(oldroot);fa[root]=0;
        }
    }
    void work()
    {
        sort(a+1,a+top+1);
        For(i,1,n)
        {
            if(opt[i][0]==1)
            {
                opt[i][1]=lower_bound(a+1,a+top+1,opt[i][1])-a;
                insert(opt[i][1]);	
            }
            else if(opt[i][0]==2)rotate_min();
            else if(opt[i][0]==3)rotate_max();
            else if(opt[i][0]==4)del_min();
            else if(opt[i][0]==5)del_max();
        }
    }
    int main()
    {
        file();
        input();
        work();
        return 0;
    }
    
  • 相关阅读:
    Install OpenCV 3.0 and Python 2.7+ on OSX
    Install OpenCV 3.0 and Python 2.7+ on Ubuntu
    完美商业计划书全攻略
    No module named zope.interface error的解决
    nginx flv点播服务器搭建
    关于Apple开发者的D-U-N-S Number
    小而美的Promise库——promiz源码浅析
    为什么JavaScript里面0.1+0.2 === 0.3是false
    JavaScript取出字符串中括号里的内容
    js数据结构与算法--递归
  • 原文地址:https://www.cnblogs.com/dengyixuan/p/8361944.html
Copyright © 2011-2022 走看看