• [CF1131F] Asya And Kittens


    Description:

    给定n个点的序列,一开始有n个块,每次将两个块合并,并告诉你这两个块中的一对元素,求一种可能的原序列

    Hint:

    (n le 1.5*10^5)

    Solution:

    实在是SB题
    考虑把每对点的祖先连上一个虚点,用并查集维护,最后dfs所得的树就行
    为什么是对的,因为这棵树会按时间顺序由下往上合并节点
    好像还有一种做法,对每个块的祖先维护一个vector表示顺序,合并时启发式合并,复杂度(O(nlogn))

    
    #include <map>
    #include <set>
    #include <stack>
    #include <cmath>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define ls p<<1 
    #define rs p<<1|1
    using namespace std;
    typedef long long ll;
    const int mxn=1e6+5; //空间开大点
    int n,hd[mxn],f[mxn],p,cnt;
    inline int read() {
    	char c=getchar(); int x=0,f=1;
    	while(c>'9'||c<'0') {if(c=='-') f=-1;c=getchar();}
    	while(c<='9'&&c>='0') {x=(x<<3)+(x<<1)+(c&15);c=getchar();}
    	return x*f;
    }
    inline int chkmax(int &x,int y) {if(x<y) x=y;}
    inline int chkmin(int &x,int y) {if(x>y) x=y;}
    
    struct ed {
    	int to,nxt;
    }t[mxn<<1];
    
    inline void add(int u,int v) {
    	t[++cnt]=(ed) {v,hd[u]}; hd[u]=cnt;
    }
    
    inline int find(int x) 
    {
    	return f[x]==x?x:f[x]=find(f[x]);
    }
    
    void dfs(int u)
    {
    	if(u<=n) printf("%d ",u); 
    	for(int i=hd[u];i;i=t[i].nxt) {
    		int v=t[i].to;
    		dfs(v);
    	}
    }
    
    int main()
    {
    	n=read(); p=n; int u,v,x,y;
    	for(int i=1;i<=mxn-2;++i) f[i]=i;
    	for(int i=1;i<n;++i) {
    		u=read(); v=read();
    		x=find(u),y=find(v);
    		f[x]=f[y]=++p;
    		add(p,x); add(p,y);
    	}
    	dfs(p);
        return 0;
    }
    
    
  • 相关阅读:
    Xcode 配置常用变量(SRCROOT, PROJECT_DIR, PROJECT_NAME)
    Git submodule实战
    Charles抓Https的包
    Vue-Quill-Editor 富文本编辑器的使用
    vue计算属性无法监听到数组内部变化
    移动端键盘弹起导致底部按钮上浮解决方案
    js中数组删除 splice和delete的区别,以及delete的使用
    js实现复制input的value到剪切板
    treetable
    vue中状态管理vuex的使用分享
  • 原文地址:https://www.cnblogs.com/list1/p/10509912.html
Copyright © 2020-2023  润新知