• BZOJ-2733 永无乡


    Treap+启发式合并。依旧没什么需要用到脑子的。

    #include <cstdlib>
    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    #include <cctype>
    #include <cstring>
    #define rep(i, l, r) for(int i=l; i<=r; i++)
    #define clr(x, c) memset(x, c, sizeof(x))
    #define maxn 100009
    using namespace std;
    inline int read()
    {
    	int x=0; char ch=getchar();
    	while (!isdigit(ch)) ch=getchar();
    	while (isdigit(ch)) x=x*10+ch-'0', ch=getchar();
    	return x;
    }
    int n=read(), m=read();
    char q[5];
    
    
    int h[maxn], l[maxn], r[maxn], s[maxn], k[maxn], pr[maxn];
    inline void Init(){srand(2); rep(i, 1, n) s[i]=1, pr[i]=rand();}
    inline void update(int x){s[x]=s[l[x]]+s[r[x]]+1;}
    inline void Left(int v)
    {
    	int u=r[v];
    	l[h[v]]==v ? l[h[v]]=u : r[h[v]]=u; h[u]=h[v];
    	r[v]=l[u], h[r[v]]=v; 
    	l[u]=v; h[v]=u; 
    	update(v), update(u);
    }
    inline void Right(int v)
    {
    	int u=l[v];
    	l[h[v]]==v ? l[h[v]]=u : r[h[v]]=u; h[u]=h[v];
    	l[v]=r[u], h[l[v]]=v;
    	r[u]=v, h[v]=u;
    	update(v), update(u);
    }
    void Insert(int v, int u)
    {
    	if (k[v] < k[u])
    	{
    		if (!l[u]) {l[u]=v, h[v]=u; update(u); return;}
    		Insert(v, l[u]); update(u);
    		if (pr[l[u]] > pr[u]) Right(u);
    	}
    	else 
    	{
    		if (!r[u]) {r[u]=v, h[v]=u, update(u); return;}
    		Insert(v, r[u]); update(u);
    		if (pr[r[u]] > pr[u]) Left(u);
    	}
    }
    int Top(int v){return h[v]==0 ? v : Top(h[v]);}
    void Join(int v, int u)
    {
    	if (v==u) return;
    	if (s[v]>s[u]) swap(v, u);
    	int a=l[v], b=r[v];
    	h[l[v]]=h[r[v]]=0, l[v]=r[v]=0, s[v]=1; 
    	Insert(v, u); 
    	if (a) Join(a, u); if (b) Join(b, u);
    }
    int Rank(int v, int k)
    {
    	if (s[v]<k) return -1; 
    	while (s[l[v]]!=k-1) if (s[l[v]]>k-1) v=l[v]; else k-=s[l[v]]+1, v=r[v];
    	return v;
    }
    
    
    
    int main()
    {
    	Init(); rep(i, 1, n) k[i]=read();
    	rep(i, 1, m) Join(Top(read()), Top(read()));
    	int o=read();
    	rep(i, 1, o)
    	{
    		int x, y; scanf("%s%d%d", q, &x, &y);
    		if (q[0]=='Q') printf("%d
    ", Rank(Top(x), y)); else Join(Top(x), Top(y));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    python format() 函数
    -bash: fork: Cannot allocate memory 问题的处理
    阿里云telnet 3306端口失败
    npm install报错 npm ERR! enoent ENOENT: no such file or directory
    springboot启动后总是自己shutdown
    thymeleaf给bootstrap自定义变量赋值
    java通过反射拷贝两个对象的同名同类型变量
    使用awk按照行数切割文件
    Iterable接口
    mac brew update 报错
  • 原文地址:https://www.cnblogs.com/NanoApe/p/4445342.html
Copyright © 2020-2023  润新知