zoukankan      html  css  js  c++  java
  • P3377 【模板】左偏树(可并堆)

    可以合并的堆。。。板子题

    以dis记录节点能向右走的最大距离

    此结构维护左子树所有dis大于等于右子树的dis。。

    题目:

    如题,一开始有N个小根堆,每个堆包含且仅包含一个数。接下来需要支持两种操作:

    操作1: 1 x y 将第x个数和第y个数所在的小根堆合并(若第x或第y个数已经被删除或第x和第y个数在用一个堆内,则无视此操作)

    操作2: 2 x 输出第x个数所在的堆最小数,并将其删除(若第x个数已经被删除,则输出-1并无视删除操作)

    so  代码。。。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<cctype>
    using namespace std;
    #define love_nmr 0
    #define olinr return
    #define nmr 150505
    int son[nmr][2];
    int fa[nmr];
    int dis[nmr];
    int val[nmr];
    int n,m;
    inline int read()
    {
        int f=1,x=0;
        char ch=getchar();
        while(!isdigit(ch))
        {
            if(ch=='-')
                f=-f;
            ch=getchar();
        }
        while(isdigit(ch))
        {
            x=(x<<1)+(x<<3)+(ch^48);
            ch=getchar();
        }
        olinr x*f;
    }
    inline void put(int x)
    {
        if(x<0)
        {
            x=-x;
            putchar('-');
        }
        if(x>9)
            put(x/10);
        putchar(x%10+'0');
    }
    inline int findset(int x)
    {
        while(fa[x]) x=fa[x];
        olinr x;
    }
    inline void swap(int &a,int &b)
    {
        int temp=a; a=b; b=temp;
    }
    inline int merge(int x,int y)
    {
        if(!x||!y) return x+y;
        if(val[x]>val[y]||(val[x]==val[y]&&x>y))
            swap(x,y);
        son[x][1]=merge(son[x][1],y);
        fa[son[x][1]]=x;
        if(dis[son[x][0]]<dis[son[x][1]])
            swap(son[x][0],son[x][1]);
        dis[x]=dis[son[x][1]]+1;
        olinr x;
    }
    inline void pop(int x)
    {
        val[x]=-1;
        fa[son[x][0]]=fa[son[x][1]]=0;
        merge(son[x][0],son[x][1]);
    }
    int main()
    {
        n=read();
        m=read();
        for(int i=1;i<=n;i++)
            val[i]=read();
        int flag,x,y;
        while(m--)
        {
            flag=read();
            if(flag==1)
            {
                x=read();
                y=read();
                if(val[x]==-1||val[y]==-1||x==y)
                    continue;
                int xx=findset(x);
                int yy=findset(y);
                merge(xx,yy);
            }
            else
            {
                x=read();
                if(val[x]==-1)
                {
                    cout<<-1<<endl;
                    continue;
                }
                y=findset(x);
                cout<<val[y]<<endl;
                pop(y);
            }
        }
        olinr love_nmr;
    }   
  • 相关阅读:
    EntityFramework优缺点
    领导者与管理者的区别
    七个对我最好的职业建议(精简版)
    The best career advice I’ve received
    Difference between Stored Procedure and Function in SQL Server
    2015年上半年一次通过 信息系统项目管理师
    Difference between WCF and Web API and WCF REST and Web Service
    What’s the difference between data mining and data warehousing?
    What is the difference between a Clustered and Non Clustered Index?
    用new创建函数的过程发生了什么
  • 原文地址:https://www.cnblogs.com/olinr/p/9448500.html
Copyright © 2011-2022 走看看