题目大意

有一棵\(n\)(\(n\leq10^5\))个节点的树,每个点有颜色\(c\),一开始所有颜色互不相同

要进行\(m\)(\(m\leq10^5\))次操作,每次操作是以下三种中的一种:

1.给出点\(x\),将点\(x\)到根路径上所有点的染成一种没出现过的颜色

2.给出点\(x\),\(y\),询问点\(x\)到\(y\)的简单路径上有多少种颜色

3.给出点\(x\),询问点\(x\)的子树中到根路径上颜色种类最多的点

题解

把1操作看成LCT的access操作,2操作就相当于询问一条链上有几条LCT里的重链,3操作相当于询问子树中到根LCT重链中最多的点

同时维护LCT和树剖,LCT为树的染色状态(同色的点在同一条重链上),树剖维护每个点\(i\)到根有几条重链,记为\(a_i\)

1操作就是LCT的access,同时树剖修改\(a_i\)

2操作的答案是\(a_x+a_y-2*a_{lca(x,y)}+1\),不用考虑重链在\(lca(x,y)\)处拐弯的情况

3操作是查询子树里\(a_i\)的最小值

代码
  1. #include<algorithm>
  2. #include<cmath>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<ctime>
  7. #include<iomanip>
  8. #include<iostream>
  9. #include<map>
  10. #include<queue>
  11. #include<set>
  12. #include<stack>
  13. #include<vector>
  14. #define rep(i,x,y) for(register int i=(x);i<=(y);++i)
  15. #define dwn(i,x,y) for(register int i=(x);i>=(y);--i)
  16. #define maxn 100010
  17. #define maxm (maxn<<1)
  18. #define view(u,k) for(int k=fir[u];k!=-1;k=nxt[k])
  19. #define ls (u<<1)
  20. #define rs (u<<1|1)
  21. #define ls2 son[u][0]
  22. #define rs2 son[u][1]
  23. #define mi (l+r>>1)
  24. using namespace std;
  25. int read()
  26. {
  27. int x=0,f=1;char ch=getchar();
  28. while(!isdigit(ch)&&ch!='-')ch=getchar();
  29. if(ch=='-')f=-1,ch=getchar();
  30. while(isdigit(ch))x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
  31. return x*f;
  32. }
  33. void write(int x)
  34. {
  35. if(x==0){putchar('0'),putchar('\n');return;}
  36. int f=0;char ch[20];
  37. if(x<0)putchar('-'),x=-x;
  38. while(x)ch[++f]=x%10+'0',x/=10;
  39. while(f)putchar(ch[f--]);
  40. putchar('\n');
  41. return;
  42. }
  43. int fir[maxn],nxt[maxm],v[maxm],now,n,q;
  44. int siz[maxn],dfn[maxn],top[maxn],fth[maxn],wson[maxn],dep[maxn],cnt,tim,to[maxn],tr[maxn<<2],mk[maxn<<2];
  45. int fa[maxn],son[maxn][2],rev[maxn],st[maxn],tp,tmpdep[maxn];
  46. void ade(int u1,int v1){v[cnt]=v1,nxt[cnt]=fir[u1],fir[u1]=cnt++;}
  47. void getson(int u)
  48. {
  49. siz[u]=1;
  50. view(u,k)if(v[k]!=fth[u])
  51. {
  52. fa[v[k]]=fth[v[k]]=u,tmpdep[v[k]]=tmpdep[u]+1,dep[v[k]]=dep[u]+1,getson(v[k]),siz[u]+=siz[v[k]];
  53. if(siz[v[k]]>siz[wson[u]])wson[u]=v[k];
  54. }
  55. }
  56. void gettop(int u,int anc)
  57. {
  58. dfn[u]=++tim,to[tim]=u,top[u]=anc;
  59. if(wson[u])gettop(wson[u],anc);
  60. view(u,k)if(v[k]!=fth[u]&&v[k]!=wson[u])gettop(v[k],v[k]);
  61. }
  62. void build(int u,int l,int r)
  63. {
  64. if(l==r){tr[u]=dep[to[l]]+1;return;}
  65. build(ls,l,mi),build(rs,mi+1,r),tr[u]=max(tr[ls],tr[rs]);return;
  66. }
  67. void mark(int u,int k){tr[u]+=k,mk[u]+=k;}
  68. void pd(int u){if(mk[u]){mark(ls,mk[u]),mark(rs,mk[u]),mk[u]=0;}}
  69. void add(int u,int l,int r,int x,int y,int k)
  70. {
  71. if(x<=l&&r<=y)return mark(u,k);
  72. pd(u);
  73. if(x<=mi)add(ls,l,mi,x,y,k);
  74. if(y>mi)add(rs,mi+1,r,x,y,k);
  75. tr[u]=max(tr[ls],tr[rs]);
  76. return;
  77. }
  78. int ask(int u,int l,int r,int x,int y)
  79. {
  80. if(x<=l&&r<=y)return tr[u];
  81. pd(u);
  82. int res=0;
  83. if(x<=mi)res=ask(ls,l,mi,x,y);
  84. if(y>mi)res=max(res,ask(rs,mi+1,r,x,y));
  85. return res;
  86. }
  87. int getso(int u){return son[fa[u]][0]!=u;}
  88. int nort(int u){return son[fa[u]][0]==u||son[fa[u]][1]==u;}
  89. void rot(int u)
  90. {
  91. int fu=fa[u],ffu=fa[fu],l=getso(u),fl=getso(fu),r=l^1,rson=son[u][r];
  92. if(nort(fu))son[ffu][fl]=u;son[fu][l]=rson,son[u][r]=fu,fa[rson]=fu,fa[u]=ffu,fa[fu]=u;
  93. }
  94. void splay(int u)
  95. {
  96. while(nort(u)){int fu=fa[u];if(nort(fu))rot(getso(u)^getso(fu)?u:fu);rot(u);}
  97. }
  98. int rnxt(int u){u=rs2;while(u){if(!ls2)break;u=ls2;}return u;}
  99. int sroot(int u){while(u&&ls2)u=ls2;return u;}
  100. void acs(int u)
  101. {
  102. for(int vv=0;u;vv=u,u=fa[u])
  103. {
  104. splay(u);
  105. int tmp=rnxt(u),tmp2=sroot(vv);
  106. rs2=vv;
  107. if(tmp){add(1,1,n,dfn[tmp],dfn[tmp]+siz[tmp]-1,1);}
  108. if(tmp2){add(1,1,n,dfn[tmp2],dfn[tmp2]+siz[tmp2]-1,-1);}
  109. }
  110. }
  111. int Lca(int x,int y)
  112. {
  113. while(top[x]!=top[y])
  114. {
  115. if(tmpdep[top[x]]<tmpdep[top[y]])swap(x,y);
  116. x=fth[top[x]];
  117. }
  118. return tmpdep[x]<tmpdep[y]?x:y;
  119. }
  120. int main()
  121. {
  122. n=read(),q=read();
  123. memset(fir,-1,sizeof(fir));
  124. rep(i,1,n-1){int x=read(),y=read();ade(x,y),ade(y,x);}
  125. getson(1),gettop(1,1),build(1,1,n);
  126. while(q--)
  127. {
  128. int f=read();
  129. if(f==1){int x=read();acs(x);}
  130. else if(f==2)
  131. {
  132. int x=read(),y=read(),lca=Lca(x,y),ansx=ask(1,1,n,dfn[x],dfn[x]),ansy=ask(1,1,n,dfn[y],dfn[y]),ansl=ask(1,1,n,dfn[lca],dfn[lca]);
  133. write(ansx+ansy-2*ansl+1);
  134. }
  135. else
  136. {
  137. int x=read();
  138. write(ask(1,1,n,dfn[x],dfn[x]+siz[x]-1));
  139. }
  140. }
  141. return 0;
  142. }

并不对劲的bzoj4817:loj2001:p3703:[SDOI2017]树点涂色的更多相关文章

  1. P3703 [SDOI2017]树点涂色

    P3703 [SDOI2017]树点涂色 链接 分析: 首先对于询问,感觉是线段树维护dfs序,每个点记录到根的颜色个数.第二问差分,第三问区间取max. 那么考虑修改,每次将一个点的颜色变成和父节点 ...

  2. Luogu P3703 [SDOI2017]树点涂色

    比较有趣的综合树上问题,刷LCT题单时做的但是发现后面LCT只是起了辅助作用233 首先我们分析每一个操作,\(1\)的定义就让我们联想到了access,我们回忆一下LCT的性质: LCT中每一个sp ...

  3. 洛谷P3703 [SDOI2017]树点涂色(LCT,dfn序,线段树,倍增LCA)

    洛谷题目传送门 闲话 这是所有LCT题目中的一个异类. 之所以认为是LCT题目,是因为本题思路的瓶颈就在于如何去维护同颜色的点的集合. 只不过做着做着,感觉后来的思路(dfn序,线段树,LCA)似乎要 ...

  4. P3703 [SDOI2017]树点涂色 LCT维护颜色+线段树维护dfs序+倍增LCA

    \(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ...

  5. 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树

    [BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...

  6. [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 692  Solved: 408[Submit][Status ...

  7. [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 629  Solved: 371[Submit][Status ...

  8. [Sdoi2017]树点涂色 [lct 线段树]

    [Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...

  9. 【LG3703】[SDOI2017]树点涂色

    [LG3703][SDOI2017]树点涂色 题面 洛谷 题解 更博辣,更博辣!!! 猪年的第一篇博客 一次只能染根到\(x\),且染的颜色未出现过 这句话是我们解题的关键. 设\(x\)到根的颜色数 ...

随机推荐

  1. HDU-1210Eddy's 洗牌问题

    Eddy's 洗牌问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Prob ...

  2. 洛谷P1757 通天之分组背包

    题目背景 直达通天路·小A历险记第二篇 题目描述 自01背包问世之后,小A对此深感兴趣.一天,小A去远游,却发现他的背包不同于01背包,他的物品大致可分为k组,每组中的物品相互冲突,现在,他想知道最大 ...

  3. 【HDOJ6315】Naive Operations(线段树,树状数组)

    题意: 两个序列a和b,初始a[i]=0,b[i]给定且为一个1到n的排列,要求维护以下两种操作:1.区间[L,R]内a[i]加1 2.询问[L,R]内a[i]/b[i](下取整)之和 n,q< ...

  4. 【BZOJ1008】越狱(排列组合计数,容斥原理)

    题意: 思路: #include<cstdio> #include<cstdlib> #include<iostream> #include<algorith ...

  5. 使用Navicat进行数据库对比同步

    使用Navicat进行数据库对比同步 当有多个数据库时,有时会出现结构或者数据不同步的问题,这时候可以使用navivat工具对比同步( 我的Navicat版本是11.0.17). 参考博客: 岁伏的博 ...

  6. python学习之-- redis模块操作 HASH

    redis 操作 之 -Hash Hash 操作:hash在内存中的存储格式 name hash n1 ------> k1 -> v1 k2 -> v2 k3 -> v3hs ...

  7. python学习之-- socketserver模块

    socketserver 模块简化了网络服务器的编写,主要实现并发的处理. 主要有4个类:这4个类是同步进行处理的,另外通过ForkingMixIn和ThreadingMixIn类来支持异步.sock ...

  8. P1420 最长连号

    洛谷——P1420 最长连号 题目描述 输入n个正整数,(1<=n<=10000),要求输出最长的连号的长度.(连号指从小到大连续自然数) 输入输出格式 输入格式: 第一行,一个数n; 第 ...

  9. Wannafly挑战赛4

    A(枚举) =w= B(枚举) 分析: 枚举每一位,考虑每位贡献,就是相当于在一段区间内找有多少1在奇数位上,有多少个1在偶数位上,维护一下各自前缀和就行了 时间复杂度O(32n) C(签到) D(d ...

  10. xml文件的schema也是经过jdk编译器编译的,如果xsd没引入完整,而xml中又用到了这些标签,就会编译不通过啊。

    1.xml文件的schema也是经过jdk编译器编译的,如果xsd没引入完整,而xml中又用到了这些标签,就会编译不通过啊. 2.java编译器会下载xsd的指定链接文件,加在代码里,一起编译