• H


    //带删除操作的并查集
    //题意:给你一个1~n的集合,有三种操作
    // 1: 把p和q所在的集合合并
    //2:把p移到q所在的集合中
    //3:返回p所在集合中的元素个数和元素的和
    
    //第二种操作不能直接把p的father改成q的father,因为这样p的子树也都换了爸爸
    //对于每个元素,我们可以记录它所在的位置pos,合并的时候新申请一个pos,然后让这个元素的位置指向pos,再把pos和q合并 
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    const int N=2e5+5;
    
    int n,m;
    int opt,p,q;
    struct Node
    {
        Node *fa,*pos;
        int key;
        int cnt,sum;
    }node[N];
    
    typedef Node* Tree;
    Tree now_node;
    
    int read()
    {
        char c=getchar();int num=0,f=1;
        for(;!isdigit(c);c=getchar())
            f=c=='-'?-1:f;
        for(;isdigit(c);c=getchar())
            return num*10+c-'0';
        return num;
    }
    
    void init()
    {
        now_node=node;
        for(int i=0;i<=n;++i,++now_node)
        {
            now_node->key=i;
            now_node->cnt=1;
            now_node->sum=i;
            now_node->fa=now_node;
            now_node->pos=now_node;
    //        (node+i)->cnt=(node+i)->sum=0;
    //        (node+i)->fa=(node+i);
    //        (node+i)->pos=(node+i);
        }
        //now_node=(node+n);
    }
    
    Tree find(Tree x)
    {
        return x->fa==x?x:x->fa=find(x->fa);
    }
    
    void unionn(Tree a,Tree b)
    {
        Tree fa=find(a),fb=find(b);
        if(fa==fb)
            return;
        fa->fa=fb;
        fb->cnt+=fa->cnt;
        fb->sum+=fa->sum;
    }
    
    void move(Tree a)
    {
        Tree fa=find(a->pos);
        --fa->cnt;
        fa->sum-=a->key;
        ++now_node;
        now_node->key=a->key;
        now_node->cnt=1;
        now_node->sum=a->key;
        now_node->fa=now_node;
        a->pos=now_node;
    }
    
    int main()
    {
        while(scanf("%d%d",&n,&m)==2)
        {
            init();
            while(--m)
            {
                opt=read();
                if(opt==1)
                {
                    p=read(),q=read();
                    unionn((node+p)->pos,(node+q)->pos);
                }
                else if(opt==2)
                {
                    p=read(),q=read();
                    Tree fa=find((node+p)->pos);
                    Tree fb=find((node+q)->pos);
                    if(fa!=fb)
                    {
                        move(node+p);
                        unionn((node+p)->pos,(node+1)->pos);
                    }
                }
                else
                {
                    p=read();
                    Tree fa=find((node+p)->pos);
                    printf("%d %d
    ",fa->cnt,fa->sum);
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    iOS学习——键盘弹出遮挡输入框问题解决方案
    知识扩展——Git和GitHub的区别
    iOS项目——项目开发环境搭建
    iOS学习——iOS项目Project 和 Targets配置详解
    iOS扩展——Objective-C开发编程规范
    iOS学习——Xcode9上传项目到GitHub
    Mac OS Sierra如何打开任何来源
    iOS学习——UIAlertController详解
    iOS学习——获取iOS设备的各种信息
    Drag and drop folder to a TextBox in C#
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8463623.html
Copyright © 2020-2023  润新知