Description

给定一棵树,边的颜色为黑或白,初始时全部为白色。维护两个操作:
1.查询u到根路径上的第一条黑色边的标号。
2.将u到v    路径上的所有边的颜色设为黑色。
Notice:这棵树的根节点为1

Input

第一行两个数n,m分别表示点数和操作数。
接下来n-1行,每行2个数u,v.表示一条u到v的边。
接下来m行,每行为以下格式:
1 v 表示第一个操作
2 v u 表示第二种操作
n,m<=10^6

Output

对于每个询问,输出相应答案。如果不存在,输出0
题解:我们将边下放到点,用点的标号来代指边
看完题面后有一个想法:用并查集维护每个白点所能到达的第一个黑点
我们知道,并查集是向上合并的
如果正着做,每一次将一条路径染黑,会导致很多白点的祖先改变,而且是向下变
向下变就十分麻烦,非常不好做
不妨逆着操作,记录每一个节点变黑的最早时间,将操作逆着进行
可以先将整棵树全部染黑,逆着逐渐染白,那么每个白点的祖先只会更向上,向上合并
比如当前要将点 $x$ 染白,那么 $x$ 子树中的白点在改动前并查集指向的祖先都是 $x$
在改动后 $x$ 的祖先会向上合并,而 $x$ 子树中的白点在并查集查祖先时查到 $x$ 的话会顺着 $x$ 向上合并到的祖先继续向上查询
  1. #include<cstdio>
  2. #include<algorithm>
  3. #include<cstring>
  4. #include<map>
  5. #include<vector>
  6. #include<stack>
  7. #include<queue>
  8. #define setIO(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
  9. #define maxn 1002002
  10. using namespace std;
  11. char *p1,*p2,buf[100000];
  12. #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
  13. int rd() {int x=0; char c=nc(); while(c<48) c=nc(); while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x;}
  14. vector<int>G[maxn];
  15. stack<int>S;
  16. int n,m,edges;
  17. int tm[maxn],hd[maxn<<1],to[maxn<<1],nex[maxn<<1];
  18. int siz[maxn],top[maxn],fa[maxn],dep[maxn],son[maxn];
  19. int idx[maxn<<1],id[maxn<<1];
  20. inline void addedge(int u,int v,int c) {
  21. nex[++edges]=hd[u],hd[u]=edges,to[edges]=v, id[edges]=c;
  22. }
  23. void dfs1(int u,int ff) {
  24. dep[u]=dep[ff]+1,siz[u]=1,fa[u]=ff;
  25. for(int i=hd[u];i;i=nex[i]) {
  26. int v=to[i];
  27. if(v==ff) continue;
  28. idx[v]=id[i], dfs1(v,u), siz[u]+=siz[v];
  29. if(siz[v] > siz[son[u]]) son[u] = v;
  30. }
  31. }
  32. void dfs2(int u,int tp) {
  33. top[u]=tp;
  34. if(son[u]) dfs2(son[u], tp);
  35. for(int i=hd[u];i;i=nex[i]) {
  36. int v=to[i];
  37. if(v==fa[u] || v==son[u]) continue;
  38. dfs2(v,v);
  39. }
  40. }
  41. inline int LCA(int x,int y) {
  42. while(top[x]^top[y]) {
  43. dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
  44. }
  45. return dep[x]<dep[y]?x:y;
  46. }
  47. struct Opt {
  48. int opt,x,y;
  49. }op[maxn];
  50. struct Union {
  51. int p[maxn];
  52. inline void init() {
  53. for(int i=0;i<maxn;++i) p[i]=i;
  54. }
  55. int find(int x) {
  56. return p[x]==x?x:p[x]=find(p[x]);
  57. }
  58. }black,white;
  59. inline void mark(int u,int lca,int cur) {
  60. u=tm[u]?black.find(u):u;
  61. while(dep[u]>dep[lca]) {
  62. tm[u]=cur;
  63. if(!tm[fa[u]]) {
  64. black.p[u]=fa[u];
  65. u=fa[u];
  66. }
  67. else {
  68. int y=black.find(fa[u]);
  69. black.p[u]=y;
  70. u=y;
  71. }
  72. }
  73. }
  74. inline void update(int u,int v,int cur) {
  75. int lca=LCA(u,v);
  76. mark(u,lca,cur), mark(v,lca,cur);
  77. }
  78. inline void change(int u) {
  79. white.p[u]=white.find(fa[u]);
  80. }
  81. int main() {
  82. // setIO("input");
  83. scanf("%d%d",&n,&m);
  84. for(int i=1;i<n;++i) {
  85. int u,v;
  86. u=rd(),v=rd();
  87. addedge(u,v,i),addedge(v,u,i);
  88. }
  89. dfs1(1,0), dfs2(1,1), black.init();
  90. for(int i=1;i<=m;++i) {
  91. op[i].opt=rd();
  92. if(op[i].opt==1) op[i].x=rd();
  93. if(op[i].opt==2) op[i].x=rd(), op[i].y=rd(), update(op[i].x,op[i].y,i);
  94. }
  95. white.init();
  96. for(int i=2;i<=n;++i) G[tm[i]==0?m+1:tm[i]].push_back(i);
  97. m+=(G[m+1].size()>1);
  98. for(int i=m;i>=1;--i) {
  99. if(G[i].size()) {
  100. for(int j=0;j<G[i].size();++j) change(G[i][j]);
  101. }else if(op[i].opt==1) {
  102. S.push(white.find(op[i].x));
  103. }
  104. }
  105. while(!S.empty()) {
  106. printf("%d\n",idx[S.top()]); S.pop();
  107. }
  108. return 0;
  109. }

  

BZOJ 3319: 黑白树 并查集 + 离线 + 思维的更多相关文章

  1. BZOJ 3319 黑白树 并查集+线段树

    这这这这这这什么毒瘤题!!!!!!!!!!!!!!!!!!!!!!!!!!!! 卡LCT(优秀的LCT由于是均摊本身就带着2,3的常数在,而且这道题对于LCT标记十分难维护,又得乘上4,5然后就炸了) ...

  2. poj 2528 Mayor's posters 线段树 || 并查集 离线处理

    题目链接 题意 用不同颜色的线段覆盖数轴,问最终数轴上有多少种颜色? 注:只有最上面的线段能够被看到:即,如果有一条线段被其他的线段给完全覆盖住,则这个颜色是看不到的. 法一:线段树 按题意按顺序模拟 ...

  3. [BZOJ 3319] 黑白树

    3319: 黑白树 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 557  Solved: 194[Submit][Status][Discuss] ...

  4. BZOJ 3319: 黑白树 树+并查集+未调完+神题

    Code: #include<bits/stdc++.h> #define maxn 1000003 using namespace std; char *p1,*p2,buf[10000 ...

  5. 【BZOJ3319】黑白树 并查集

    [BZOJ3319]黑白树 Description 给定一棵树,边的颜色为黑或白,初始时全部为白色.维护两个操作:1.查询u到根路径上的第一条黑色边的标号.2.将u到v    路径上的所有边的颜色设为 ...

  6. BZOJ 3211 线段树+并查集

    思路: 我们很容易发现 一个数开根号 开几(很小)次 就到了1 1 再怎么开 都是1 由于这个性质 我们就可以用并查集 了 //By SiriusRen #include <cmath> ...

  7. [HDU3710] Battle Over Cities [树链剖分+线段树+并查集+kruskal+思维]

    题面 一句话题意: 给定一张 N 个点, M 条边的无向连通图, 每条边上有边权 w . 求删去任意一个点后的最小生成树的边权之和. 思路 首先肯定要$kruskal$一下 考虑$MST$里面去掉一个 ...

  8. 【BZOJ】3319: 黑白树(并查集+特殊的技巧/-树链剖分+线段树)

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 以为是模板题就复习了下hld............................. 然后n ...

  9. 【BZOJ】3319: 黑白树

    http://www.lydsy.com/JudgeOnline/problem.php?id=3319 题意:给一棵n节点的树(n<=1e6),m个操作(m<=1e6),每次操作有两种: ...

随机推荐

  1. Servlet 三种创建方式

    servlet 是运行在 Web 服务器(tomcat)中的小型 Java 程序(即:服务器端的小应用程序) (其实就是一个java类,只不过不用再new了).servlet 通常通过 HTTP(超文 ...

  2. IP子网的划分

    一.划分子网的具体步骤 已知192.168.1.0/24,划分8个子网(一个ip划分8个子网,即网络位不再是24位)1100 0000.1010 1000.0000 0001.0000 00001 . ...

  3. 安装Git并关联

    下载git 打开git bash 生成key将 key绑定到帐号 输入命令 ssh-keygen -t rsa -C 'LoginName' 根据命令生成的地址找到对应文件复制密钥 打开github登 ...

  4. Java String == && equal

    [.net超级群:27921837] Java中equals和==的区别 java中的数据类型,可分为两类:1.基本数据类型,也称原始数据类型.byte,short,char,int,long,flo ...

  5. linux sed 命令 实现对文件的增删改替换查 实验

    1. 统一实验文本 # 创建包含下面内容的文件,后面的操作都会使用这个文件 [root@MongoDB ~]# cat person.txt ,mike,CEO ,jack,CTO ,yy,CFO , ...

  6. Nginx跨域问题

    Nginx跨域无法访问,通常报错: Failed to load http://172.18.6.30:8086/CityServlet: No 'Access-Control-Allow-Origi ...

  7. JS跨域--window.name

    JS跨域--window.name:https://www.jianshu.com/p/43ff69d076e3

  8. phpstudy添加PHP

    想在phpstudy2018里面增加一个php版本,操作如下: 一.下载php-7.2.19-ts文件,解压缩,放在相应的目录下: 二.修改Apache的配置文件1.修改httpd.conf 配置,D ...

  9. Java关于继承中的内存分配

    1.定义         super:当前对象的父类对象         this   :当前对象,谁调用this所在的方法,this就是哪一个对象.   2.内存分析 另一个例子: public s ...

  10. Houdini:也许是你未曾听过的最振奋人心的 CSS 进化

    原文链接:Houdini: Maybe The Most Exciting Development In CSS You’ve Never Heard Of更多译文将陆续推出,欢迎点赞+收藏+关注我的 ...