zoukankan      html  css  js  c++  java
  • BZOJ 2733 永无乡

    这题splay启发式合并。。。也就是暴力插入。

    然而为什么要写一个并查集?

    不是为了找splay的根。。。只是为了判断是不是在一个集合内,不是就break掉。

    5s作死啦。。。。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #define maxv 100500
    using namespace std;
    int n,m,q,x,y,tree[maxv][3],size[maxv],fath[maxv],val[maxv],finds[maxv];
    char s[5];
    bool isroot(int x)
    {
        return tree[fath[x]][1]!=x&&tree[fath[x]][2]!=x;
    }
    void pushup(int x)
    {
        int ls=tree[x][1],rs=tree[x][2];
        size[x]=size[ls]+size[rs]+1;
    }
    int getfather(int x)
    {
        if (x!=finds[x])
            finds[x]=getfather(finds[x]);
        return finds[x];
    }
    void insert(int node,int x,int now,int father)
    {
        if (now==0)
        {
            fath[node]=father;
            if (x>val[father]) tree[father][2]=node;
            else tree[father][1]=node;
            tree[node][1]=0;tree[node][2]=0;
            size[node]=1;
            return;
        }
        if (x>val[now]) insert(node,x,tree[now][2],now);
        else insert(node,x,tree[now][1],now);
        pushup(now);
    }
    void rotate(int x)
    {
        int y=fath[x],z=fath[y],l,r;
        if (tree[y][1]==x) l=1;else l=2;
        r=3-l;
        if (!isroot(y))
        {
            if (tree[z][1]==y) tree[z][1]=x;
            else tree[z][2]=x;
        }
        fath[x]=z;fath[y]=x;fath[tree[x][r]]=y;
        tree[y][l]=tree[x][r];tree[x][r]=y;
        pushup(y);pushup(x);
    }
    void splay(int x)
    {
        while (!isroot(x))
        {
            int y=fath[x],z=fath[y];
            if (!isroot(y))
            {
                if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x);
                else rotate(y);
            }
            rotate(x);
        }
    }
    void bfs(int x,int y)
    {
        queue <int> q;
        q.push(x);
        while (!q.empty())
        {
            int head=q.front();
            q.pop();
            insert(head,val[head],y,y);
            if (tree[head][1]) q.push(tree[head][1]);
            if (tree[head][2]) q.push(tree[head][2]);
        }
    }
    void unionn(int x,int y)
    {
        int f1=getfather(x),f2=getfather(y);
        if (f1==f2) return;
        splay(x);splay(y);
        if (size[x]>size[y]) swap(x,y);
        bfs(x,y);finds[x]=y;
    }
    int ask(int now,int k)
    {
        int ls=tree[now][1],rs=tree[now][2];
        if (size[ls]>=k) return ask(ls,k);
        else if (size[ls]<k-1) return ask(rs,k-size[ls]-1);
        else return now; 
    }
    void work1()
    {
        scanf("%d%d",&x,&y);
        splay(x);
        if (size[x]<y) {printf("-1
    ");return;}
        int ans=ask(x,y);
        printf("%d
    ",ans);
        splay(ans);
    }
    void work2()
    {
        scanf("%d%d",&x,&y);
        unionn(x,y);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&val[i]);
            size[i]=1;
            finds[i]=i;
        }
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            unionn(x,y);
        }
        scanf("%d",&q);
        for (int i=1;i<=q;i++)
        {
            scanf("%s",s);
            if (s[0]=='Q') work1();
            else work2();
        }
        return 0;
    }
  • 相关阅读:
    solaris如何启动ssh服务
    网页实现插入图片—css与html的区别
    Python与RPC -- (转)
    Python中的异常处理 -- (转)
    Python的异常处理机制 -- (转)
    HTML 学习
    链表练习 链表反转 链表插入..
    php解决抢购秒杀抽奖等大流量并发入库导致的库存负数的问题
    PHP队列的实现 算法
    利用redis List队列简单实现秒杀 PHP代码实现
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5475541.html
Copyright © 2011-2022 走看看