2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB

Submit: 4537  Solved: 1702

[

id=2243" style="color:blue; text-decoration:none">Submit][Status][

id=2243" style="color:blue; text-decoration:none">Discuss]

Description

给定一棵有n个节点的无根树和m个操作,操作有2类:

1、将节点a到节点b路径上全部点都染成颜色c;

2、询问节点a到节点b路径上的颜色段数量(连续同样颜色被觉得是同一段)。如“112221”由3段组成:“11”、“222”和“1”。

请你写一个程序依次完毕这m个操作。

Input

第一行包括2个整数n和m,分别表示节点数和操作数;

第二行包括n个正整数表示n个节点的初始颜色

以下 行每行包括两个整数x和y,表示xy之间有一条无向边。

以下 行每行描写叙述一个操作:

“C a b c”表示这是一个染色操作。把节点a到节点b路径上全部点(包含a和b)都染成颜色c;

“Q a b”表示这是一个询问操作。询问节点a到节点b(包含a和b)路径上的颜色段数量。

Output

对于每一个询问操作,输出一行答案。

Sample Input

6 5



2 2 1 2 1 1



1 2



1 3



2 4



2 5



2 6



Q 3 5



C 2 1 1



Q 3 5



C 5 1 2



Q 3 5


Sample Output

3



1



2

HINT

数N<=10^5。操作数M<=10^5,全部的颜色C为整数且在[0, 10^9]之间。

Source

有关链的操作,非常显然树链剖分+线段树维护区间。

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<cmath>
  5. #include<cstdlib>
  6. #include<algorithm>
  7. #define F(i,j,n) for(int i=j;i<=n;i++)
  8. #define D(i,j,n) for(int i=j;i>=n;i--)
  9. #define ll long long
  10. #define maxn 100005
  11. using namespace std;
  12. struct seg{int l,r,lc,rc,s,tag;}t[maxn*4];
  13. struct edge_type{int next,to;}e[maxn*2];
  14. int n,m,x,y,z,cnt,tot;
  15. int head[maxn],d[maxn],son[maxn],belong[maxn],p[maxn],a[maxn],f[maxn][18];
  16. char ch;
  17. bool vst[maxn];
  18. inline int read()
  19. {
  20. int x=0,f=1;char ch=getchar();
  21. while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
  22. while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
  23. return x*f;
  24. }
  25. inline void add_edge(int x,int y)
  26. {
  27. e[++cnt]=(edge_type){head[x],y};head[x]=cnt;
  28. e[++cnt]=(edge_type){head[y],x};head[y]=cnt;
  29. }
  30. inline void dfs1(int x)
  31. {
  32. vst[x]=true;son[x]=1;
  33. for(int i=1;i<=17;i++)
  34. {
  35. if (d[x]<(1<<i)) break;
  36. f[x][i]=f[f[x][i-1]][i-1];
  37. }
  38. for(int i=head[x];i;i=e[i].next)
  39. {
  40. if (vst[e[i].to]) continue;
  41. d[e[i].to]=d[x]+1;
  42. f[e[i].to][0]=x;
  43. dfs1(e[i].to);
  44. son[x]+=son[e[i].to];
  45. }
  46. }
  47. inline void dfs2(int x,int chain)
  48. {
  49. p[x]=++tot;belong[x]=chain;
  50. int k=0;
  51. for(int i=head[x];i;i=e[i].next)
  52. if (d[e[i].to]>d[x]&&son[k]<son[e[i].to]) k=e[i].to;
  53. if (!k) return;
  54. dfs2(k,chain);
  55. for(int i=head[x];i;i=e[i].next)
  56. if (d[e[i].to]>d[x]&&e[i].to!=k) dfs2(e[i].to,e[i].to);
  57. }
  58. inline int lca(int x,int y)
  59. {
  60. if (d[x]<d[y]) swap(x,y);
  61. int t=d[x]-d[y];
  62. F(i,0,17) if (t&(1<<i)) x=f[x][i];
  63. if (x==y) return x;
  64. D(i,17,0) if (f[x][i]!=f[y][i]){x=f[x][i];y=f[y][i];}
  65. return f[x][0];
  66. }
  67. inline void build(int k,int l,int r)
  68. {
  69. t[k].l=l;t[k].r=r;t[k].s=1;t[k].tag=-1;
  70. if (l==r) return;
  71. int mid=(l+r)>>1;
  72. build(k<<1,l,mid);
  73. build(k<<1|1,mid+1,r);
  74. }
  75. inline void pushup(int k)
  76. {
  77. t[k].lc=t[k<<1].lc;t[k].rc=t[k<<1|1].rc;
  78. if (t[k<<1].rc==t[k<<1|1].lc) t[k].s=t[k<<1].s+t[k<<1|1].s-1;
  79. else t[k].s=t[k<<1].s+t[k<<1|1].s;
  80. }
  81. inline void update(int k,int z)
  82. {
  83. t[k].tag=t[k].lc=t[k].rc=z;
  84. t[k].s=1;
  85. }
  86. inline void pushdown(int k)
  87. {
  88. if (t[k].tag==-1) return;
  89. update(k<<1,t[k].tag);
  90. update(k<<1|1,t[k].tag);
  91. t[k].tag=-1;
  92. }
  93. inline void change(int k,int l,int r,int x)
  94. {
  95. if (t[k].l==l&&t[k].r==r){update(k,x);return;}
  96. pushdown(k);
  97. int mid=(t[k].l+t[k].r)>>1;
  98. if (r<=mid) change(k<<1,l,r,x);
  99. else if (l>mid) change(k<<1|1,l,r,x);
  100. else{change(k<<1,l,mid,x);change(k<<1|1,mid+1,r,x);}
  101. pushup(k);
  102. }
  103. inline int ask(int k,int l,int r)
  104. {
  105. if (t[k].l==l&&t[k].r==r) return t[k].s;
  106. pushdown(k);
  107. int mid=(t[k].l+t[k].r)>>1;
  108. if (r<=mid) return ask(k<<1,l,r);
  109. else if (l>mid) return ask(k<<1|1,l,r);
  110. else
  111. {
  112. int tmp=t[k<<1].rc==t[k<<1|1].lc;
  113. return ask(k<<1,l,mid)+ask(k<<1|1,mid+1,r)-tmp;
  114. }
  115. }
  116. inline int getc(int k,int pos)
  117. {
  118. if (t[k].l==t[k].r) return t[k].lc;
  119. pushdown(k);
  120. int mid=(t[k].l+t[k].r)>>1;
  121. if (pos<=mid) return getc(k<<1,pos);
  122. else return getc(k<<1|1,pos);
  123. }
  124. inline void solvechange(int x,int t,int c)
  125. {
  126. while (belong[x]!=belong[t])
  127. {
  128. change(1,p[belong[x]],p[x],c);
  129. x=f[belong[x]][0];
  130. }
  131. change(1,p[t],p[x],c);
  132. }
  133. inline int solvesum(int x,int t)
  134. {
  135. int sum=0;
  136. while (belong[x]!=belong[t])
  137. {
  138. sum+=ask(1,p[belong[x]],p[x]);
  139. if (getc(1,p[belong[x]])==getc(1,p[f[belong[x]][0]])) sum--;
  140. x=f[belong[x]][0];
  141. }
  142. sum+=ask(1,p[t],p[x]);
  143. return sum;
  144. }
  145. int main()
  146. {
  147. n=read();m=read();
  148. F(i,1,n) a[i]=read();
  149. F(i,1,n-1){x=read();y=read();add_edge(x,y);}
  150. dfs1(1);
  151. dfs2(1,1);
  152. build(1,1,n);
  153. F(i,1,n) change(1,p[i],p[i],a[i]);
  154. F(i,1,m)
  155. {
  156. ch=getchar();
  157. while (ch<'A'||ch>'Z') ch=getchar();
  158. if (ch=='Q')
  159. {
  160. x=read();y=read();
  161. int t=lca(x,y);
  162. printf("%d\n",solvesum(x,t)+solvesum(y,t)-1);
  163. }
  164. else
  165. {
  166. x=read();y=read();z=read();
  167. int t=lca(x,y);
  168. solvechange(x,t,z);solvechange(y,t,z);
  169. }
  170. }
  171. }

bzoj2243【SDOI2011】染色的更多相关文章

  1. BZOJ2243 SDOI2011 染色 【树链剖分】

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

  2. bzoj2243[SDOI2011]染色 树链剖分+线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 9012  Solved: 3375[Submit][Status ...

  3. [bzoj2243][SDOI2011]染色

    Description 给定一棵有$n$个节点的无根树和$m$个操作,操作有$2$类: 1.将节点$a$到节点$b$路径上所有点都染成颜色$c$; 2.询问节点$a$到节点$b$路径上的颜色段数量(连 ...

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

    题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221 ...

  5. [BZOJ2243][SDOI2011]染色 解题报告|树链剖分

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“ ...

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

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

  7. BZOJ2243: [SDOI2011]染色(树链剖分/LCT)

    Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如 ...

  8. bzoj2243: [SDOI2011]染色--线段树+树链剖分

    此题代码量较大..但是打起来很爽 原本不用lca做一直wa不知道为什么.. 后来改lca重打了一遍= =结果一遍就AC了orz 题目比较裸,也挺容易打,主要是因为思路可以比较清晰 另:加读入优化比没加 ...

  9. BZOJ2243——[SDOI2011]染色

    1.题目大意:给个树,然后树上每个点都有颜色,然后会有路径的修改,有个询问,询问一条路径上的颜色分成了几段 2.分析:首先这个修改是树剖可以做的,对吧,但是这个分成了几段怎么搞呢,我们的树剖的不是要建 ...

  10. bzoj2243 sdoi2011 染色 paint

    明明是裸树剖 竟然调了这么久好蛋疼 大概是自己比较水的原因吧 顺便+fastio来gangbang #include<iostream> #include<cstring> # ...

随机推荐

  1. Microsoft SQL Server学习(四)--约束

    SQLServer - 约束 主要是为了保证数据库中的数据一致性.有效性.准确性, 从而提高了数据库中数据的正确性 一.约束的分类 在SQLserver中,约束分三种不同类型 1.实体约束 实提约束是 ...

  2. vue+vux+es6+webpack移动端常用配置步骤

    1.创建项目(vue项目的流程就不多讲了)2.cnpm install vux --save3.在build/webpack.base.conf.js配置:const vuxLoader = requ ...

  3. cookie、json详解

    什么是cookie 1.cookie是存储于访问者计算机中的变量2.cookie是浏览器提供的一种机制3.可以由js控制(设置.读取.删除)4.cookie可以实现跨页面全局变量可以跨越同域名下多个网 ...

  4. Thread stack overrun

    ERROR 1436 (HY000): Thread stack overrun:  6448 bytes used of a 131072 byte stac k, and 128000 bytes ...

  5. 【译】x86程序员手册30-8.2 I/O指令

    8.2 I/O Instructions I/O指令 The I/O instructions of the 80386 provide access to the processor's I/O p ...

  6. 6.11 将分割数据转换为多值IN列表

    问题 已经有了分隔数据,想要将其转换为WHERE子句IN列表中的项目.考虑下面的字符串: 7654,7698,7782,7788 要将该字符串用在WHERE子句中,但是下面的SQL语句是错误的,因为E ...

  7. 用 webpack 实现持久化缓存

    什么是持久化缓存? 原文链接https://sebastianblade.com/using-webpack-to-achieve-long-term-cache/ 缓存(cache)一直是前端性能优 ...

  8. Python数据分析与展示(1)-数据分析之表示(2)-NumPy数据存取与函数

    NumPy数据存取与函数 数据的CSV文件存取 CSV文件 CSV(Comma-Separated Value,逗号分隔值) CSV是一种常见的文件格式,用来存储批量数据. 将数据写入CSV文件 np ...

  9. 爬楼梯,N级楼梯有多少种走法?

    https://blog.csdn.net/tcpipstack/article/details/45173685 一个人爬楼梯,一步可以迈一级,二级,三级台阶,如果楼梯有N级,要求编写程序,求总共有 ...

  10. BZOJ 4094 USACO 2013 Dec. Optimal Milking

    线段树 每个节点保存4个值,both表示左右端点都取,neither表示左右端点都不取,left表示只取左端点,right表示只取右端点. 维护的特殊姿势: $cur$的$both=max(ls.l+ ...