Code:

#include<bits/stdc++.h>
#define maxn 1000003
using namespace std;
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0,f=1; char c=nc(); while(c<48) {if(c=='-') f=-1; c=nc();} while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x*f;}
void setIO(string s)
{
    string in=s+".in", out=s+".out";
    freopen(in.c_str(),"r",stdin);
    freopen(out.c_str(),"w",stdout);
}
int n,Q,edges;
int hd[maxn],to[maxn<<1],nex[maxn<<1],val[maxn<<1],fa[maxn],dep[maxn],p[maxn],mark[maxn],tag[maxn];
int pd[maxn], answer[maxn];
void Init()
{
    for(int i=0;i<maxn;++i) p[i]=i;
}
int find(int x)
{
    return p[x]==x?x:p[x]=find(p[x]);
}
void addedge(int u,int v,int c)
{
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v,val[edges]=c;
}
void dfs(int u,int ff)
{
    fa[u]=ff;
    for(int i=hd[u];i;i=nex[i])
    {
        int v=to[i];
        if(v==ff) continue;
        dep[v]=dep[u]+1;
        mark[v]=val[i];
        dfs(v,u);
    }
}
struct OPT
{
    int o,u,v;
}opt[maxn];
void _2(int u,int v,int cur)
{
    u=find(u),v=find(v);
    while(u!=v)
    {
        // v is deeper than u
        if(dep[u] > dep[v]) swap(u,v);
        if(!pd[v]) p[v]=find(fa[v]), pd[v]=cur;
       //  printf("%d %d\n",dep[u],dep[v]);
        v = p[v];
    }
}
//set u -> v to white
void solve(int u,int v,int cur)
{
    u=find(u),v=find(v);
    while(u!=v)
    {
        if(dep[u] > dep[v]) swap(u,v);
        if(pd[v]==cur) p[v]=find(fa[v]);
        v = p[fa[v]];                  // 暴力跳QAQ......
        //v=p[v];
    }
}
int main()
{
  //   setIO("input");
   // scanf("%d%d",&n,&Q);
    n=rd(),Q=rd();
    for(int i=1;i<n;++i)
    {
        int u,v;
        u=rd(),v=rd();
        //scanf("%d%d",&u,&v);
        addedge(u,v,i);
        addedge(v,u,i);
    }
    dep[1]=1;
    dfs(1,0);
    for(int i=1;i<=Q;++i)
    {
        opt[i].o=rd();
        //scanf("%d",&opt[i].o);
        if(opt[i].o==1)  opt[i].u=rd();
           // scanf("%d",&opt[i].u);
        else opt[i].u=rd(), opt[i].v=rd();
           // scanf("%d%d",&opt[i].u,&opt[i].v);
    }
    // 处理黑点情况.
    Init();
    for(int i=1;i<=Q;++i)
    {
        if(opt[i].o==2) _2(opt[i].u,opt[i].v,i);
    }
    Init();
    for(int i=2;i<=n;++i)
    {
        if(!pd[i])               //到最后也未被染成黑色 直接用并查集连上
        {
            int u = fa[i], v = i;
            int x = find(u);
            p[v] = x;
        }
    }
    int tot = 0;
    for(int i=Q;i>=1;--i)
    {
        if(opt[i].o==2)
        {
            //debug();
            solve(opt[i].u, opt[i].v, i);
            // debug();
        }
        else
        {
            int x = find(opt[i].u);
            answer[++tot]=mark[x];
        }
    }
    for(int i=tot;i>=1;--i) printf("%d\n",answer[i]);
    return 0;
}

  

BZOJ 3319: 黑白树 树+并查集+未调完+神题的更多相关文章

  1. 【BZOJ2733】永无乡(线段树,并查集)

    [BZOJ2733]永无乡(线段树,并查集) 题面 BZOJ 题解 线段树合并 线段树合并是一个很有趣的姿势 前置技能:动态开点线段树 具体实现:每次合并两棵线段树的时候,假设叫做\(t1,t2\), ...

  2. 2019牛客暑期多校训练营(第八场)E:Explorer(LCT裸题 也可用线段树模拟并查集维护连通性)

    题意:给定N,M,然后给出M组信息(u,v,l,r),表示u到v有[l,r]范围的通行证有效.问有多少种通行证可以使得1和N连通. 思路:和bzoj魔法森林有点像,LCT维护最小生成树.  开始和队友 ...

  3. Educational Codeforces Round 51 (Rated for Div. 2) G. Distinctification(线段树合并 + 并查集)

    题意 给出一个长度为 \(n\) 序列 , 每个位置有 \(a_i , b_i\) 两个参数 , \(b_i\) 互不相同 ,你可以进行任意次如下的两种操作 : 若存在 \(j \not = i\) ...

  4. BZOJ4399魔法少女LJJ——线段树合并+并查集

    题目描述 在森林中见过会动的树,在沙漠中见过会动的仙人掌过后,魔法少女LJJ已经觉得自己见过世界上的所有稀奇古怪的事情了LJJ感叹道“这里真是个迷人的绿色世界,空气清新.淡雅,到处散发着醉人的奶浆味: ...

  5. 2018.09.30 bzoj4025: 二分图(线段树分治+并查集)

    传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...

  6. 洛谷P3402 【模板】可持久化并查集 [主席树,并查集]

    题目传送门 可持久化并查集 n个集合 m个操作 操作: 1 a b 合并a,b所在集合 2 k 回到第k次操作之后的状态(查询算作操作) 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0 ...

  7. 洛谷P4121 [WC2005]双面棋盘(线段树套并查集)

    传送门 先膜一下大佬->这里 据说这题正解是LCT,然而感觉还是线段树套并查集的更容易理解 我们对于行与行之间用线段树维护,每一行内用并查集暴力枚举 每一行内用并查集暴力枚举连通块这个应该容易理 ...

  8. BZOJ.2054.疯狂的馒头(并查集)

    BZOJ 倒序处理,就是并查集傻题了.. 并查集就是确定下一个未染色位置的,直接跳到那个位置染.然而我越想越麻烦=-= 以为有线性的做法,发现还是要并查集.. 数据随机线段树也能过去. //18400 ...

  9. BZOJ 4195: [Noi2015]程序自动分析 并查集+离散化

    LUOGU 1955BZOJ 4195 题目描述 在实现程序自动分析的过程中,常常需要判定一些约束条件是否能被同时满足. 考虑一个约束满足问题的简化版本:假设x1,x2,x3...代表程序中出现的变量 ...

随机推荐

  1. [bzoj2213][Poi2011]Difference_动态规划

    Difference bzoj-2213 Poi-2011 题目大意:已知一个长度为n的由小写字母组成的字符串,求其中连续的一段,满足该段中出现最多的字母出现的个数减去该段中出现最少的字母出现的个数最 ...

  2. 洛谷 P2023 [AHOI2009]维护序列

    P2023 [AHOI2009]维护序列 题目描述 老师交给小可可一个维护数列的任务,现在小可可希望你来帮他完成. 有长为N的数列,不妨设为a1,a2,…,aN .有如下三种操作形式: (1)把数列中 ...

  3. supervisord进程管理工具小结

    前言 昨天临近下班,发现业务队列处理不及时,正好想到不久之前,上了一个新功能:通过队列异步转发微信消息.可能是消息太多了处理不过来,没怎么多想,处理不过来了,多增加处理进程就可以了,后来发现自己so ...

  4. 相克军_Oracle体系_随堂笔记 PPT

    http://www.cnblogs.com/jyzhao/category/581259.html http://download.csdn.net/detail/yzj149286454/8960 ...

  5. gap lock/next-key lock浅析Basic-Paxos协议日志同步应用

    http://www.cnblogs.com/renolei/p/4673842.html 当InnoDB在判断行锁是否冲突的时候, 除了最基本的IS/IX/S/X锁的冲突判断意外, InnoDB还将 ...

  6. PHP array_diff_assoc()

    定义和用法 array_diff_assoc() 函数返回两个数组的差集数组.返回的数组的元素都取自被比较的数组(既第一个数组). 和 array_diff() 函数 不同,本函数要求键名和键值都进行 ...

  7. 在centos7上安装DSPC

    感谢朋友支持本博客.欢迎共同探讨交流,因为能力和时间有限.错误之处在所难免,欢迎指正! 假设转载,请保留作者信息. 博客地址:http://blog.csdn.net/qq_21398167 原博文地 ...

  8. stl变易算法(三)

    本篇接着前面stl变易算法(一)和stl变易算法(二)继续讲述变易算法. 这里将介绍完余下的变易算法,主要有:填充fill.n次填充fill_n.随机生成元素generate.随机生成n个元素gene ...

  9. vim中凝视多行python代码

    在vim中凝视多行python代码比較麻烦,主要由下面几种方法: (1)将须要凝视的代码以文档字符串的形式呈现 (2)将须要凝视的代码以函数的形式呈现 (3)使用vim自身快捷键 我们主要使用第三种方 ...

  10. Ant报错之out of memory

    用Ant打包一个比較大的项目的时候,遇到OutOfMemory的问题,求助于Google和百度,网上的解决方式非常多,可是个人认为不够具体全面.我的问题须要综合两种方法才解决.把方案记下来.以期帮助大 ...