「SDOI2017」树点涂色

我sb的不行了


其实一开始有一个类似动态dp的想法

每个点维护到lct树上到最浅点的颜色段数,然后维护一个\(mx_{0,1}\)也就是是否用虚儿子的最大颜色

用个set维护一下虚儿子

但是啊,我发现搞这个区间改颜色的时候,虚儿子好像得用树套树维护,我当场就不行了...


每个点如果维护到根的颜色段数\(f\)

然后发现啊,这个你如果用一个lct的一个子树维护同一种颜色,在你access的时候实变虚或者虚变实对子树有一个+1或者-1

然后额外在外面开一个线段树维护子树加减,每次access的时候操作

然后这个颜色段比较特殊,链的颜色个数可以\(f_u+f_v-f_{lca(u,v)}*2+1\),这个简单讨论一下就好了

操作3就是区间最大值


Code:

  1. #include <cstdio>
  2. #include <cctype>
  3. #include <cstring>
  4. #include <algorithm>
  5. using std::max;
  6. template <class T>
  7. void read(T &x)
  8. {
  9. x=0;char c=getchar();
  10. while(!isdigit(c)) c=getchar();
  11. while(isdigit(c)) x=x*10+c-'0',c=getchar();
  12. }
  13. const int N=1e5+10;
  14. int n,m;
  15. int head[N],to[N<<1],Next[N<<1],cnt;
  16. void add(int u,int v)
  17. {
  18. to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
  19. }
  20. int mx[N<<2],tag[N<<2];
  21. int dfn[N],low[N],dep[N],yuy[N],f[20][N],dfsclock;
  22. int LCA(int x,int y)
  23. {
  24. if(dep[x]<dep[y]) std::swap(x,y);
  25. for(int i=18;~i;i--)
  26. if(dep[f[i][x]]>=dep[y])
  27. x=f[i][x];
  28. if(x==y) return x;
  29. for(int i=18;~i;i--)
  30. if(f[i][x]!=f[i][y])
  31. x=f[i][x],y=f[i][y];
  32. return f[0][x];
  33. }
  34. void pushdown(int id)
  35. {
  36. if(tag[id])
  37. {
  38. tag[id<<1]+=tag[id];
  39. tag[id<<1|1]+=tag[id];
  40. mx[id<<1]+=tag[id];
  41. mx[id<<1|1]+=tag[id];
  42. tag[id]=0;
  43. }
  44. }
  45. void build(int id,int l,int r)
  46. {
  47. if(l==r) {mx[id]=yuy[l];return;}
  48. int mid=l+r>>1;
  49. build(id<<1,l,mid),build(id<<1|1,mid+1,r);
  50. mx[id]=max(mx[id<<1],mx[id<<1|1]);
  51. }
  52. void modify(int id,int L,int R,int l,int r,int d)
  53. {
  54. if(l==L&&r==R)
  55. {
  56. mx[id]+=d;
  57. tag[id]+=d;
  58. return;
  59. }
  60. pushdown(id);
  61. int Mid=L+R>>1;
  62. if(r<=Mid) modify(id<<1,L,Mid,l,r,d);
  63. else if(l>Mid) modify(id<<1|1,Mid+1,R,l,r,d);
  64. else modify(id<<1,L,Mid,l,Mid,d),modify(id<<1|1,Mid+1,R,Mid+1,r,d);
  65. mx[id]=max(mx[id<<1],mx[id<<1|1]);
  66. }
  67. int query(int id,int l,int r,int p)
  68. {
  69. if(l==r) return mx[id];
  70. pushdown(id);
  71. int mid=l+r>>1;
  72. if(p<=mid) return query(id<<1,l,mid,p);
  73. else return query(id<<1|1,mid+1,r,p);
  74. }
  75. int query(int id,int L,int R,int l,int r)
  76. {
  77. if(L==l&&R==r) return mx[id];
  78. pushdown(id);
  79. int Mid=L+R>>1;
  80. if(r<=Mid) return query(id<<1,L,Mid,l,r);
  81. else if(l>Mid) return query(id<<1|1,Mid+1,R,l,r);
  82. else return max(query(id<<1,L,Mid,l,Mid),query(id<<1|1,Mid+1,R,Mid+1,r));
  83. }
  84. int ch[N][2],par[N],Lef[N];
  85. #define fa par[now]
  86. #define ls ch[now][0]
  87. #define rs ch[now][1]
  88. bool isroot(int now){return ch[fa][0]==now||ch[fa][1]==now;}
  89. int identity(int now){return ch[fa][1]==now;}
  90. void connect(int f,int now,int typ){ch[fa=f][typ]=now;}
  91. void updata(int now)
  92. {
  93. Lef[now]=now;
  94. if(ls) Lef[now]=Lef[ls];
  95. }
  96. void Rotate(int now)
  97. {
  98. int typ=identity(now),p=fa;
  99. connect(p,ch[now][typ^1],typ);
  100. if(isroot(p)) connect(par[p],now,identity(p));
  101. else fa=par[p];
  102. connect(now,p,typ^1);
  103. updata(p),updata(now);
  104. }
  105. void splay(int now)
  106. {
  107. for(;isroot(now);Rotate(now))
  108. if(isroot(fa))
  109. Rotate(identity(fa)^identity(now)?now:fa);
  110. }
  111. void access(int now)
  112. {
  113. for(int las=0;now;las=now,now=fa)
  114. {
  115. splay(now);
  116. if(rs)
  117. modify(1,1,n,dfn[Lef[rs]],low[Lef[rs]],1);
  118. if(las)
  119. modify(1,1,n,dfn[Lef[las]],low[Lef[las]],-1);
  120. rs=las;
  121. updata(now);
  122. }
  123. }
  124. void dfs(int now,int dis)
  125. {
  126. dfn[now]=++dfsclock;
  127. yuy[dfsclock]=dis;
  128. dep[now]=dep[par[now]=f[0][now]]+1;
  129. for(int i=1;f[i-1][now];i++) f[i][now]=f[i-1][f[i-1][now]];
  130. for(int v,i=head[now];i;i=Next[i])
  131. if((v=to[i])!=f[0][now])
  132. f[0][v]=now,dfs(v,dis+1);
  133. low[now]=dfsclock;
  134. }
  135. int main()
  136. {
  137. read(n),read(m);
  138. for(int u,v,i=1;i<n;i++) read(u),read(v),add(u,v),add(v,u);
  139. dfs(1,1);
  140. build(1,1,n);
  141. for(int op,x,y,i=1;i<=m;i++)
  142. {
  143. read(op),read(x);
  144. if(op==1) access(x);
  145. else if(op==2)
  146. {
  147. read(y);
  148. printf("%d\n",query(1,1,n,dfn[x])+query(1,1,n,dfn[y])-(query(1,1,n,dfn[LCA(x,y)])<<1)+1);
  149. }
  150. else
  151. printf("%d\n",query(1,1,n,dfn[x],low[x]));
  152. }
  153. return 0;
  154. }

2019.4.10

「SDOI2017」树点涂色 解题报告的更多相关文章

  1. loj2001 「SDOI2017」树点涂色

    there #include <iostream> #include <cstdio> using namespace std; int n, m, dfn[100005], ...

  2. 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]

    树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MB[Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中1 ...

  3. [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]

    题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...

  4. 「NOI2013」小 Q 的修炼 解题报告

    「NOI2013」小 Q 的修炼 第一次完整的做出一个提答,花了半个晚上+一个上午+半个下午 总体来说太慢了 对于此题,我认为的难点是观察数据并猜测性质和读入操作 我隔一会就思考这个sb字符串读起来怎 ...

  5. 「SCOI2015」小凸想跑步 解题报告

    「SCOI2015」小凸想跑步 最开始以为和多边形的重心有关,后来发现多边形的重心没啥好玩的性质 实际上你把面积小于的不等式列出来,发现是一次的,那么就可以半平面交了 Code: #include & ...

  6. 「SCOI2015」小凸解密码 解题报告

    「SCOI2015」小凸解密码 题意:给一个环,定义一段连续的极长\(0\)串为\(0\)区间,定义一个位置的离一个\(0\)区间的距离为这个位置离这个区间中\(0\)的距离的最小值,每次询问一个位置 ...

  7. 「SCOI2015」小凸玩矩阵 解题报告

    「SCOI2015」小凸玩矩阵 我好沙茶啊 把点当边连接行和列,在外面二分答案跑图的匹配就行了 我最开始二分方向搞反了,样例没过. 脑袋一抽,这绝壁要费用流,连忙打了个KM 然后wa了,一想这个不是完 ...

  8. 「SCOI2015」小凸玩密室 解题报告

    「SCOI2015」小凸玩密室 虽然有心里在想一些奇奇怪怪的事情的原因,不过还是写太久了.. 不过这个题本身也挺厉害的 注意第一个被点亮的是任意选的,我最开始压根没注意到 \(dp_{i,j}\)代表 ...

  9. 「SCOI2014」方伯伯运椰子 解题报告

    「SCOI2014」方伯伯运椰子 可以看出是分数规划 然后我们可以看出其实只需要改变1的流量就可以了,因为每次改变要保证流量守恒,必须流成一个环,在正负性确定的情况下,变几次是无所谓的. 然后按照套路 ...

随机推荐

  1. jQuery中的prop()和attr()的区别

    1.jQuery中的prop()和attr()的区别 prop()是在jQuery1.6版本之后才有的,在之前一直都是使用attr(), prop()修复了attr()的一些小bug. 2.推荐用法: ...

  2. JFreeChart画图+jsp页面显示实现统计图

    1 开发环境: 1.eclipse(可替换) 2.jfreechart-1.0.19 2 说明: (1) source目录:为 jfreechart的源码目录:不会的主要看这里.因为他的文档是收费的. ...

  3. Java虚拟机垃圾收集算法

    1.标记-清除算法 标记-清除算法分为 "标记" 和 "清除" 两个步骤:首先标记出所有需要回收的对象,然后在标记完成后统一回收所有被标记的对象,是垃圾收集算法 ...

  4. Head First设计模式读书笔记

    阅读指南: 精读一章内容,手工输入一章代码(注1),与书中描述的思想进行印证,实在搞不懂就放过吧.设计模式绝对不会一次就看懂的. 这本书对于理解设计模式很有帮助,就是例子不太符合中国人的思维模式,但是 ...

  5. js中console使用1

    js中console主要用于debug时使用 测试代码如下: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN ...

  6. socket字符流循环截取

    场景:socket 客户端将一个单向链表序列化后发送给服务端,服务端将之解析,重新构建单向链表. Client.cpp //遍历链表,填充到缓冲区 ]) { ListNode* tmp = p; // ...

  7. vs code配置flutter开发android

    下载flutter_sdk压缩包,解压到指定目录,把sdk的bin目录添加到系统环境变量Path 设置中国临时镜像:添加两个系统变量 FLUTTER_STORAGE_BASE_URL=https:// ...

  8. java集合介绍(List,Set,Map)

    前言 介绍java的常用集合+各个集合使用用例 欢迎转载,请注明作者和出处哦☺ 参考: 1,<Java核心编程技术(第二版)> 2, http://www.cnblogs.com/Litt ...

  9. DVWA 黑客攻防演练(十四)CSRF 攻击 Cross Site Request Forgery

    这么多攻击中,CSRF 攻击,全称是 Cross Site Request Forgery,翻译过来是跨站请求伪造可谓是最防不胜防之一.比如删除一篇文章,添加一笔钱之类,如果开发者是没有考虑到会被 C ...

  10. DVWA 黑客攻防演练(十二) DOM型 XSS 攻击 DOM Based Cross Site Scripting

    反射型攻击那篇提及到,如何是"数据是否保存在服务器端"来区分,DOM 型 XSS 攻击应该算是 反射型XSS 攻击. DOM 型攻击的特殊之处在于它是利用 JS 的 documen ...