终于做了一道不是一眼出思路的代码题(⊙o⊙)

之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱)

实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开线段树的时候记录一下就好了

事实上我开了一个node,并且写了一个mix还是大大减小了代码量(对于我这种手残党来说同时大大减小了错误率)

由于前几题做的都是树链剖分,并没有在这一方面出问题,然而线段树还是不熟练,刚写完的时候居然忘记down了(mdzz)

对wa了N遍的总结:

由于是树上两个点间的路径,既有向上的路也有向下的路,然而树剖下来的结果是按深度排的,所以在链上跑的时候会发现一段链的左右(l和r)有时候是相反的,在合并几条链的时候一定要注意(事实证明我这么多遍wa全是因为没有翻转链)

对这一类问题的总结:

对于每一段都考虑有用(会对周围产生影响)的信息,在染色段数中就是两端(因为可能和隔壁合并)

  1. //加了一大堆斜杠的是第一遍写之后补的
  2. #include <cstdio>
  3. #include <iostream>
  4. #define mid (l+r)/2
  5. using namespace std;
  6. int m=,N=,n,M,p,q,o;
  7. int to[],nex[],fir[],son[],bro[],co[];
  8. int size[],l[],pos[],fa[],h[],top[];
  9. struct node{int s,l,r;bool b;}t[],ans[];
  10. inline void add(int x,int y){to[++m]=y;nex[m]=fir[x];fir[x]=m;}
  11. inline node mix(node x,node y){return (node){x.s+y.s-(x.r==y.l),x.l,y.r,};}
  12. int build(int now,int fat)
  13. {
  14. size[now]=;fa[now]=fat;h[now]=h[fat]+;
  15. for(int i=fir[now];i;i=nex[i])
  16. if(to[i]!=fat)
  17. size[now]+=build(to[i],now),bro[to[i]]=son[now],son[now]=to[i];
  18. return size[now];
  19. }
  20. void pou(int now,int to)
  21. {
  22. l[++N]=now;pos[now]=N;top[now]=to;
  23. int max=son[now];
  24. if(!max) return;
  25. for(int i=bro[max];i;i=bro[i])
  26. if(size[i]>size[max]) max=i;
  27. pou(max,to);
  28. for(int i=son[now];i;i=bro[i])
  29. if(i!=max) pou(i,i);
  30. }
  31. void down(int now)////////////////////////////
  32. {
  33. if(t[now].b)
  34. {
  35. t[now].b=;t[now*].b=t[now*+].b=;
  36. t[now*].s=t[now*+].s=;
  37. t[now*].l=t[now*].r=t[now*+].l=t[now*+].r=t[now].l;
  38. }
  39. }
  40. void work(int now,int l,int r,int x,int y,int z)
  41. {
  42. if(l==x && r==y)
  43. { t[now]=(node){,z,z,}; return;}
  44. down(now);
  45. if(x<=mid)
  46. work(now*,l,mid,x,min(y,mid),z);
  47. if(y>mid)
  48. work(now*+,mid+,r,max(x,mid+),y,z);
  49. t[now]=mix(t[now*],t[now*+]);
  50. }
  51. node que(int now,int l,int r,int x,int y)
  52. {
  53. if(l==x && r==y)
  54. return t[now];
  55. down(now);
  56. if(y<=mid) return que(now*,l,mid,x,y);
  57. if(x>mid) return que(now*+,mid+,r,x,y);
  58. return mix(que(now*,l,mid,x,mid),que(now*+,mid+,r,mid+,y));
  59. }
  60. void solve(int x,int y,int z)
  61. {
  62. bool b=;ans[]=ans[]=(node){,-,-,};
  63. while(top[x]!=top[y])
  64. {
  65. if(h[top[x]]<h[top[y]]) swap(x,y),b=!b;
  66. if(z==-)
  67. {
  68. node tem=que(,,n,pos[top[x]],pos[x]);
  69. if(!b) swap(tem.l,tem.r);///////////////////////////////
  70. if(ans[b].s==) ans[b]=tem;
  71. else
  72. ans[b]=b?mix(tem,ans[b]):mix(ans[b],tem);
  73. }
  74. else
  75. work(,,n,pos[top[x]],pos[x],z);
  76. x=fa[top[x]];
  77. }
  78. if(h[x]>h[y]) swap(x,y),b=!b;//////////////////
  79. if(z==-)
  80. {
  81. node tem=que(,,n,pos[x],pos[y]);b=!b;////////////////
  82. if(!b) swap(tem.l,tem.r);
  83. if(ans[b].s==) ans[b]=tem;
  84. else
  85. ans[b]=b?mix(tem,ans[b]):mix(ans[b],tem);
  86. printf("%d\n",mix(ans[],ans[]).s);
  87. }
  88. else
  89. work(,,n,pos[x],pos[y],z);
  90. }
  91. int main()
  92. {
  93. scanf("%d%d",&n,&M);
  94. for(int i=;i<=n;i++)
  95. scanf("%d",&co[i]);
  96. for(int i=;i<n;i++)
  97. scanf("%d%d",&p,&q),add(p,q),add(q,p);
  98. build(,);
  99. pou(,);
  100. for(int i=;i<=n;i++)
  101. work(,,n,pos[i],pos[i],co[i]);
  102. for(int i=;i<=M;i++)
  103. {
  104. char ch=getchar();
  105. while(ch!='C' && ch!='Q') ch=getchar();
  106. if(ch=='C')
  107. scanf("%d%d%d",&p,&q,&o),solve(p,q,o);
  108. else
  109. scanf("%d%d",&p,&q),solve(p,q,-);
  110. }
  111. return ;
  112. }

bzoj2243树链剖分+染色段数的更多相关文章

  1. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  2. bzoj2243 树链剖分

    https://www.lydsy.com/JudgeOnline/problem.php?id=2243 新学的树剖,在维护的时候线段树维护区间内颜色数量以及左右两端的颜色.统计的时候区间合并时判断 ...

  3. bzoj2243树链剖分+区间合并

    树链上区间合并的问题比区间修改要复杂,因为每一条重链在线段树上分布一般都是不连续的,所以在进行链上操作时要手动将其合并起来,维护两个端点值 处理时的方向问题:lca->u是一个方向,lca-&g ...

  4. [SDOI2011]染色 BZOJ2243 树链剖分+线段树

    分析: 区间合并,lcol是左端点的颜色编号,rcol是右端点的颜色编号,那么我们向上合并的时候,如果左儿子的rcol等于右儿子的lcol那么区间的sum--. 另外,如果重链顶的颜色等于重链顶的父节 ...

  5. hdu3966 树链剖分+成段更新

    给你n个点,m条边,p次操作.n个点相连后是一棵树.每次操作可以是x 到 y 增加 z,或者减z,或者问当前点的值是多少. 可以将树分成链,每个点在线段树上都有自己的点,然后线段树成段更新一下. #p ...

  6. BZOJ2243 [SDOI2011]染色(树链剖分+线段树合并)

    题目链接 BZOJ2243 树链剖分 $+$ 线段树 线段树每个节点维护$lc$, $rc$, $s$ $lc$代表该区间的最左端的颜色,$rc$代表该区间的最右端的颜色 $s$代表该区间的所有连续颜 ...

  7. HDU3966-Aragorn's Story(树链剖分)

    第一道树链剖分. 早就想学..一直懒.. 感觉还是比较简单的. 主要是要套其他数据结构,线段树大概还好,平衡树之类的肯定就跪了. http://blog.csdn.net/acdreamers/art ...

  8. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  9. BZOJ2243 洛谷2486 [SDOI2011]染色 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2243 题目传送门 - 洛谷2486 题意概括 一棵树,共n个节点. 让你支持以下两种操作,共m次操 ...

随机推荐

  1. maven实战(02)_坐标详解

    (一)  何为mave坐标 maven的世界中拥有数量非常巨大的构件,也就是平时用的一些jar,war等文件. maven定义了这样一组规则: 世界上任何一个构件都可以使用Maven坐标唯一标志,ma ...

  2. MAC下apache+php

    mac下是自带有Apache和php的服务器的,不需要另外安装,本文就对相关配置进行介绍. 第一:Apache 在终端中输入,下面指令即可启动Apache服务器: //启动 sudo apachect ...

  3. 架构和模式的区别:三层架构和MVC在应用开发中的位置

    架构是系统层面的,可以是多层架构,也可以是事件驱动架构,也可以是微服务架构. 模式是GUI应用的一种职责分离设计. 三层架构(包含多层架构)和 MVC模式(包含MVP, MVVM) 没什么关系,它们不 ...

  4. pwd命令

    [pwd]      打印当前的工作目录             pwd==print work director 命令格式: pwd [OPTION]... 命令功能: 打印当前工作目录的全路径 命 ...

  5. HTML DOM Event 对象

    var event;if (document.createEvent){event = document.createEvent("HTMLEvents");event.initE ...

  6. qt 定时器

    重写方法 virtual void timerEvent(QTimerEvent *event); 启动定时器 timerId = startTimer(500);

  7. java十进制转十六进制

    package com.ds.detect; import java.util.Scanner; public class ToHEX{ public static void main(String[ ...

  8. zsh 自动补全导致命令显示重复

    关键字:autocomplete, zsh, backspace, securecrt, xterm, linux console 举个例子: 输入命令ls  然后按TAB补全试试,发现竟然是这样的 ...

  9. 解决浏览器Adobe Flash Player不是最新版本问题

    关键:选择谷歌浏览器的PPAPI版本的flash下载直接安装即可 搜索: Adobe Flash Player PPAPI 下载地址: http://www.wmzhe.com/soft-30259. ...

  10. CozyRSS开发记录13-添加订阅的对话框

    CozyRSS开发记录13-添加订阅的对话框 1.设计对话框 首先,还是先用MockPlus来画个原型图: 因为用了MaterialDesignToolkit,那么可以很方便的有一个蒙层的效果. 2. ...