cnbb 我被数组清零卡了一天..

子树改色询问子树颜色数..

先考虑颜色为x的节点对祖先答案的贡献,那么我们考虑把所有这些节点都搞出来,按dfs序排序,然后考虑每个节点a掌管的祖先是它和按dfs序的下一个同色节点b的LCA以下的节点,然后每个有颜色x儿子的树都被覆盖了,而且最多覆盖一次.

在删除节点的时候考虑将所有它的儿子删去变成一棵只有根节点的树.

统计答案的时候要考虑父亲的贡献..即若这个节点的颜色在它子树中出现了答案就不+1,否则答案+1.

cnbb的多组数据, fuck you.

数据复杂度\(O((n+q)\log{n})\)

至于为什么是这样注意到加入节点的次数是\(O(n+q)\)的,加入或删去一个节点的复杂度是\(O(\log{n})\)的.

树上链加单点查询只需要考虑儿子对它所有祖先的贡献,然后改区间询问单点修改就可以了,BIT维护.

  1. #include <set>
  2. #include <map>
  3. #include <cstdio>
  4. #include <cstring>
  5. #include <algorithm>
  6. // Contants & usable functions
  7. using namespace std;
  8. const int N = 500010;
  9. // Debug functions(mostly macros)
  10. int out(int p){ return p; }
  11. typedef int(*FII)(int);
  12. #ifdef MacroDebug
  13. #define debug(...) { fprintf(stderr, ##__VA_ARGS__); fflush(stdout); }
  14. inline void printset(set<int> p, FII Fn=out){
  15. debug("Set :");
  16. for(set<int>::iterator k=p.begin();k!=p.end();++k) debug(" %d",Fn(*k));
  17. debug("\n");
  18. }
  19. #else
  20. #define debug(...)
  21. inline void printset(set<int> p, FII Fn=out){}
  22. #endif
  23. // Tree(LCA, Left, Right, DfsSeq, Depth, Size)
  24. struct ed{
  25. int t;
  26. ed*n;
  27. }*h[N],Al[N<<1],*p=Al;
  28. inline void ade(int f,int t){ *p=(ed){t,h[f]}; h[f]=p++; }
  29. int DfsSeq[N<<1] , DfsMark ;
  30. int Left [N] , Right[N];
  31. int Father[N] , Size [N];
  32. int maxson[N] , Depth[N];
  33. int dfs(int t,int f=0){
  34. Father[t]=f, ++DfsMark, Size[t]=1, Depth[t]=Depth[f]+1;
  35. Left[DfsSeq[DfsMark]=t]=DfsMark;
  36. for(ed*i=h[t];i;i=i->n)if(i->t!=f){
  37. Size[t]+=dfs(i->t,t);
  38. if(Size[i->t]>Size[maxson[t]]) maxson[t]=i->t;
  39. } Right[t]=DfsMark;
  40. return Size[t];
  41. }
  42. inline void clearTree(){ for(int i=0;i<=DfsMark;++i) h[i]=NULL,Depth[i]=maxson[i]=Size[i]=0; p=Al; }
  43. #ifdef MacroDebug
  44. int OutUnSeq(int t){ return DfsSeq[t]; }
  45. #else
  46. const FII OutUnSeq=out;
  47. #endif
  48. int top[N];
  49. int dfs2(int t,int Top){
  50. top[t]=Top;
  51. if(maxson[t]) dfs2(maxson[t],Top);
  52. for(ed*i=h[t];i;i=i->n)if(i->t!=Father[t]&&i->t!=maxson[t]) dfs2(i->t,i->t);
  53. }
  54. inline int LCA(int u,int v){
  55. int fu=top[u], fv=top[v];
  56. while(fu!=fv){
  57. if(Depth[fu]<Depth[fv]) swap(fu,fv),swap(u,v);
  58. u=Father[fu];
  59. fu=top[u];
  60. } return Depth[u]<Depth[v]?u:v;
  61. }
  62. // Path add, point query
  63. #define lb(x) (x&-x)
  64. template<int T=N<<1> struct BIT{
  65. int bitarr[T],siz;
  66. inline void clear(){ for(int i=0;i<=siz;++i) bitarr[i]=0; siz=0; }
  67. inline void init(int n){ clear(), siz=n; }
  68. inline void add(int t,int w){ for(;t<=siz;t+=lb(t)) bitarr[t]+=w; }
  69. inline int sum(int t){ int ans=0; for(;t;t-=lb(t)) ans+=bitarr[t]; return ans; }
  70. inline int sum(int l,int r){ return sum(r)-sum(l-1); }
  71. };
  72. BIT<> TPU;
  73. inline void Add(int f,int t,int g=1){
  74. debug("1: %d %d %d\n",f,t,g);
  75. TPU.add(Left[f],g);
  76. if(t) TPU.add(Left[t],-g);
  77. }
  78. inline int Qry(int f){ return TPU.sum(Left[f],Right[f]); }
  79. // The colors on the tree
  80. namespace colorSeg{
  81. int col[N<<2];
  82. void build(int i,int l,int r){
  83. col[i]=-1;
  84. if(l==r){
  85. col[i]=0;
  86. return;
  87. } int mid=(l+r)>>1;
  88. build(i<<1,l,mid), build(i<<1|1,mid+1,r);
  89. }
  90. inline void pd(int t){ if(~col[t]) col[t<<1]=col[t<<1|1]=col[t], col[t]=-1; }
  91. void upd(int i,int l,int r,int ql,int qr,int cl){
  92. if(ql<=l && r<=qr) col[i]=cl;
  93. else{ int mid=(l+r)>>1; pd(i);
  94. if(ql<=mid) upd(i<<1,l,mid,ql,qr,cl);
  95. if(qr> mid) upd(i<<1|1,mid+1,r,ql,qr,cl);
  96. }
  97. }
  98. int GetColor(int i,int l,int r,int t){ int mid=(l+r)>>1;
  99. if(l==r) return col[i];
  100. else return pd(i),(t<=mid)?GetColor(i<<1,l,mid,t):GetColor(i<<1|1,mid+1,r,t);
  101. }
  102. inline void set(int f,int val){ upd(1,1,DfsMark,Left[f],Right[f],val); }
  103. inline int get(int f){ return GetColor(1,1,DfsMark,Left[f]); }
  104. };
  105. // Stores All Colors & Deletable Tree
  106. typedef set<int> si;
  107. typedef si::iterator sit;
  108. si colors[N];
  109. int Pcolor[N];
  110. int PathUpto[N];
  111. inline void Reinit(int nk){ for(int i=1;i<=nk;++i) colors[i].clear(), PathUpto[i]=-1; }
  112. inline void ReColor(int q,int RecolorQ=-1){
  113. debug("Recolor %d -- %d\n",q,RecolorQ);
  114. if(~PathUpto[q]){
  115. debug("FStart\n");
  116. Add(q,PathUpto[q],-1), PathUpto[q]=-1;
  117. colors[Pcolor[q]].erase(Left[q]);
  118. debug("Color %d ",Pcolor[q]);
  119. printset(colors[Pcolor[q]],OutUnSeq);
  120. debug("FEnd\n");
  121. } if(~RecolorQ) Pcolor[q]=RecolorQ;
  122. if(Pcolor[q]){
  123. int colorx=Pcolor[q];
  124. debug("Color %d ",colorx);
  125. printset(colors[colorx],OutUnSeq);
  126. sit v=colors[colorx].lower_bound(Left[q]);
  127. if(v!=colors[colorx].end()){
  128. int ar=DfsSeq[*v];
  129. PathUpto[q]=LCA(q,ar);
  130. }else PathUpto[q]=0;
  131. debug("Update PathUpto %d\n",PathUpto[q]);
  132. Add(q,PathUpto[q]);
  133. colors[colorx].insert(Left[q]);
  134. }
  135. }
  136. inline void deletePoint(int t){
  137. if(int qc=Pcolor[t]){
  138. ReColor(t,0);
  139. sit k=colors[qc].lower_bound(Left[t]);
  140. if(k!=colors[qc].begin()) ReColor(DfsSeq[*(--k)]);
  141. }
  142. }
  143. inline void insertPoint(int t,int color){
  144. deletePoint(t);
  145. if(color){
  146. ReColor(t,color);
  147. debug("Color %d Find %d ",color,t);
  148. printset(colors[color],OutUnSeq);
  149. sit v=colors[color].find(Left[t]);
  150. if(v!=colors[color].begin()) ReColor(DfsSeq[*(--v)]);
  151. }
  152. }
  153. namespace treeSeg{
  154. int Has[N<<2];
  155. void build(int i,int l,int r){
  156. Has[i]=0; int mid=(l+r)>>1;
  157. if(l==r) return;
  158. build(i<<1,l,mid), build(i<<1|1,mid+1,r);
  159. }
  160. int sum(int i,int l,int r,int ql,int qr,int ans=0){ int mid=(l+r)>>1;
  161. if(ql<=l && r<=qr) return Has[i];
  162. else{
  163. if(ql<=mid) ans+=sum(i<<1,l,mid,ql,qr);
  164. else ans+=sum(i<<1|1,mid+1,r,ql,qr);
  165. return ans;
  166. }
  167. }
  168. int clr(int i,int l,int r,int ql,int qr){ int mid=(l+r)>>1;
  169. if(l==r) deletePoint(DfsSeq[l]),Has[i]=0;
  170. else{
  171. if(ql<=mid && Has[i<<1]) clr(i<<1,l,mid,ql,qr);
  172. if(qr> mid && Has[i<<1|1]) clr(i<<1|1,mid+1,r,ql,qr);
  173. Has[i]=Has[i<<1]+Has[i<<1|1];
  174. }
  175. }
  176. void set(int i,int l,int r,int t){
  177. if(l==r){
  178. Has[i]=1;
  179. return;
  180. }
  181. int mid=(l+r)>>1;
  182. if(t<=mid) set(i<<1,l,mid,t);
  183. else set(i<<1|1,mid+1,r,t);
  184. Has[i]=Has[i<<1]+Has[i<<1|1];
  185. }
  186. inline void Color(int f){ set(1,1,DfsMark,Left[f]); }
  187. inline void Delete(int f){ if(Left[f]==Right[f]) return; clr(1,1,DfsMark,Left[f]+1,Right[f]); }
  188. };
  189. inline void Color(int f,int val){
  190. insertPoint(f,val);
  191. treeSeg::Delete(f);
  192. treeSeg::Color (f);
  193. colorSeg::set(f,val);
  194. }
  195. inline int Query(int f){
  196. int ccol=colorSeg::get(f);
  197. int target=0x7fffffff;
  198. sit v=colors[ccol].lower_bound(Left[f]);
  199. if(v!=colors[ccol].end()) target=*v;
  200. return (Qry(f)+1)-(target<=Right[f]?1:0);
  201. }
  202. inline void Work(int t){
  203. static int vc[N];
  204. printf("Case #%d:\n",t);
  205. clearTree();
  206. int n; scanf("%d",&n);
  207. for(int i=1,a,b;i<n;++i){
  208. scanf("%d%d",&a,&b);
  209. ade(a,b); ade(b,a);
  210. }
  211. DfsMark=0;
  212. dfs(1), dfs2(1,1);
  213. TPU.init(DfsMark);
  214. colorSeg::build(1,1,DfsMark);
  215. treeSeg ::build(1,1,DfsMark);
  216. Reinit(n);
  217. for(int i=1;i<=n;++i)
  218. colors[i].clear();
  219. for(int i=1;i<=n;++i)
  220. scanf("%d",vc+i), Pcolor[i]=0;
  221. for(int i=1;i<=n;++i)
  222. Color(DfsSeq[i],vc[DfsSeq[i]]);
  223. int q; scanf("%d",&q);
  224. for(int i=1;i<=q;++i){
  225. int a,u,c;
  226. scanf("%d%d",&a,&u);
  227. if(a){
  228. int q=Query(u);
  229. printf("%d\n",q);
  230. debug("%d\n",q);
  231. }
  232. else scanf("%d",&c),Color(u,c);
  233. }
  234. }
  235. int main(){
  236. int t; scanf("%d",&t);
  237. for(int i=1;i<=t;++i) Work(i);
  238. return 0;
  239. }

Colorful tree的更多相关文章

  1. 2017 Multi-University Training Contest - Team 1 1003&&HDU 6035 Colorful Tree【树形dp】

    Colorful Tree Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  2. hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。

    /** 题目:hdu6035 Colorful Tree 链接:http://acm.hdu.edu.cn/showproblem.php?pid=6035 题意:给定一棵树,每个节点有一个颜色值.定 ...

  3. AtCoder Beginner Contest 133 F Colorful Tree

    Colorful Tree 思路: 如果强制在线的化可以用树链剖分. 但这道题不强制在线,那么就可以将询问进行差分,最后dfs时再计算每个答案的修改值, 只要维护两个数组就可以了,分别表示根节点到当前 ...

  4. HDU 6035 - Colorful Tree | 2017 Multi-University Training Contest 1

    /* HDU 6035 - Colorful Tree [ DFS,分块 ] 题意: n个节点的树,每个节点有一种颜色(1~n),一条路径的权值是这条路上不同的颜色的数量,问所有路径(n*(n-1)/ ...

  5. [HDU6793] Tokitsukaze and Colorful Tree

    题目 又是一个条历新年,窗前的灼之花又盛开了. 时隔多年,现在只有这一棵树上盛开着残存的 \(n\) 朵灼之花了. 尽管如此,这些灼之 花仍散发出不同色彩的微弱的光芒. 灼之花的生命极为短暂,但它的花 ...

  6. 2017ACM暑期多校联合训练 - Team 1 1003 HDU 6035 Colorful Tree (dfs)

    题目链接 Problem Description There is a tree with n nodes, each of which has a type of color represented ...

  7. HDU-6035:Colorful Tree(虚树+DP)

    这里有三道长得像的题: 一:HDU6036: There is a tree with nn nodes, each of which has a type of color represented ...

  8. ABC133F - Colorful Tree

    ABC133FColorful Tree 题意 给定一颗边有颜色和权值的树,多次询问,每次询问,首先更改颜色为x的边的权值为y,然后输出u到v的距离. 数据都是1e5量级的. 思路 我自己一开始用树链 ...

  9. HDU6035 Colorful Tree

    题目链接:https://vjudge.net/problem/HDU-6035 题目大意: 多样例输入. 对于每一个样例,给出 n \((2 \le n \le 200000)\) 个结点的一棵树, ...

随机推荐

  1. time模块

    In [1]: import time In [2]: import datetime In [3]: date_time = datetime.datetime.now() In [4]: prin ...

  2. Ankh不起作用的解决方法

    请检查Visual Studio 2008的Tool > Options... > Source Control,在下拉菜单中选择插件.

  3. 图片延迟加载jquery插件imgLazyLoad(三)

    此Jquery插件是在图片加载前显示一个加载图片,当图片下载完毕后显示图片出来,可对图片进行是否自动缩放功能,此Jquery插件使用时可让页面先加载,而图片后加载的方式,解决了平时使用时要在图片显示出 ...

  4. 合并两个结构完全相同的DataTable

    两个结构一模一样的DataTable如何合并? 例子:使用Winform进行演示,表2的数据为固定的,表1的数据可以动态添加,通过合并按钮合并表1和表2的数据到表3 1.规定公共的DataTable结 ...

  5. mysql 简单练习

    1.查找全部学生的信息 [SQL]select * from student 受影响的行: 0 时间: 0.000s 2.查出成绩及格的所有人 [SQL]select * from student w ...

  6. thinkphp单入口和多入口的访问方法

    完全是参考thinkphp的官网资料 现在, 基本上都是 用 单入口 的方式来做的! thinkphp可创建多入口和单入口两种模式,本文主要讲解创建方法和两者的区别. TP版本:3.1.3 前端:Ho ...

  7. 机器学习的5种语言(选自info world)

    摘要:机器学习目前炙手可热,本文搜集了Java.Python以及go等编程语言中常见且实用的开源机器学习工具,对机器学习感兴趣的开发者或者准备和机器学习打交道的数据科学家们不能错过了 [编者按] 机器 ...

  8. for 循环中 i++和 ++i

    在标准C语言中, i++和 ++i的区别显而易见. 但是,当在for循环中使用 i++和 ++i的时候,会发现.只要这两种语句不用来赋值操作(作为右值,赋值给左值),那么这两种写法其实是一样的. fo ...

  9. objective-c与c++的差异

    oc的编译指令为 clang -fobjc-arc -framework Foundation test.m -o test oc中,1表示YES,0表示NO.并不是非0值都是YES,这是因为BOOL ...

  10. 工具介绍 - VSCommands

    VSCommands 一个Visual Studio的轻量级扩展工具 地址:http://vscommands.squaredinfinity.com/home 1.可以设置自动隐藏显示主菜单栏,设置 ...