码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 2733 永无乡

时间:2016-05-09 22:00:25      阅读:251      评论:0      收藏:0      [点我收藏+]

标签:

这题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\n");return;}
    int ans=ask(x,y);
    printf("%d\n",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;
}

 

BZOJ 2733 永无乡

标签:

原文地址:http://www.cnblogs.com/ziliuziliu/p/5475541.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!