题目链接:

2243: [SDOI2011]染色

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit: 6267  Solved: 2291

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]之间。

题意:

思路:

树链剖分的入门题?反正上次写hdu边那个一个T,今天写这个点的版本的还好;调了一会就过了;

AC代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long LL;
  4. #define lson o<<1
  5. #define rson o<<1|1
  6. const int maxn=1e5+10;
  7. int n,m,a[maxn];
  8. int siz[maxn],dep[maxn],fa[maxn],son[maxn],top[maxn],tid[maxn],Rank[maxn],tim=0;
  9. vector<int>ve[maxn];
  10. void dfs1(int cur,int father,int deep)
  11. {
  12. fa[cur]=father;
  13. siz[cur]=1;
  14. dep[cur]=deep;
  15. int len=ve[cur].size();
  16. for(int i=0;i<len;i++)
  17. {
  18. int x=ve[cur][i];
  19. if(x==father)continue;
  20. dfs1(x,cur,deep+1);
  21. siz[cur]+=siz[x];
  22. if(son[cur]==-1||siz[x]>siz[son[cur]])son[cur]=x;
  23. }
  24. }
  25. void dfs2(int cur,int tp)
  26. {
  27. top[cur]=tp;
  28. tid[cur]=++tim;
  29. Rank[tim]=cur;
  30. if(son[cur]==-1)return ;
  31. dfs2(son[cur],tp);
  32. int len=ve[cur].size();
  33. for(int i=0;i<len;i++)
  34. {
  35. int x=ve[cur][i];
  36. if(x==fa[cur]||x==son[cur])continue;
  37. dfs2(x,x);
  38. }
  39. }
  40. struct Tree
  41. {
  42. int l,r,sum,lc,rc,mark;
  43. }tr[maxn*4];
  44. inline void pushup(int o)
  45. {
  46. tr[o].sum=tr[lson].sum+tr[rson].sum;
  47. tr[o].lc=tr[lson].lc;tr[o].rc=tr[rson].rc;
  48. if(tr[lson].rc==tr[rson].lc)tr[o].sum--;
  49. }
  50. inline void pushdown(int o)
  51. {
  52. if(tr[o].mark>=0)
  53. {
  54. tr[lson].sum=tr[rson].sum=1;
  55. tr[lson].lc=tr[lson].rc=tr[o].mark;
  56. tr[rson].lc=tr[rson].rc=tr[o].mark;
  57. tr[lson].mark=tr[rson].mark=tr[o].mark;
  58. tr[o].mark=-1;
  59. }
  60. }
  61. void build(int o,int L,int R)
  62. {
  63. tr[o].l=L;tr[o].r=R;
  64. tr[o].mark=-1;
  65. if(L>=R)
  66. {
  67. tr[o].sum=1;
  68. tr[o].lc=tr[o].rc=a[Rank[L]];
  69. return ;
  70. }
  71. int mid=(L+R)>>1;
  72. build(lson,L,mid);
  73. build(rson,mid+1,R);
  74. pushup(o);
  75. }
  76. void update(int o,int L,int R,int num)
  77. {
  78. if(L<=tr[o].l&&R>=tr[o].r)
  79. {
  80. tr[o].sum=1;
  81. tr[o].lc=tr[o].rc=num;
  82. tr[o].mark=num;
  83. return ;
  84. }
  85. int mid=(tr[o].l+tr[o].r)>>1;
  86. pushdown(o);
  87. if(L<=mid)update(lson,L,R,num);
  88. if(R>mid)update(rson,L,R,num);
  89. pushup(o);
  90. }
  91. int query(int o,int L,int R,int & Lc,int & Rc)
  92. {
  93. if(L<=tr[o].l&&R>=tr[o].r)
  94. {
  95. if(L==tr[o].l)Lc=tr[o].lc;
  96. if(R==tr[o].r)Rc=tr[o].rc;
  97. return tr[o].sum;
  98. }
  99. int mid=(tr[o].l+tr[o].r)>>1;
  100. pushdown(o);
  101. if(R<=mid)return query(lson,L,R,Lc,Rc);
  102. else if(L>mid)return query(rson,L,R,Lc,Rc);
  103. else
  104. {
  105. int ans=query(lson,L,R,Lc,Rc)+query(rson,L,R,Lc,Rc);
  106. if(tr[lson].rc==tr[rson].lc)ans--;
  107. return ans;
  108. }
  109. }
  110.  
  111. void change(int u,int v,int w)
  112. {
  113. int fu=top[u],fv=top[v];
  114.  
  115. while(fu!=fv)
  116. {
  117. if(dep[fu]<dep[fv])swap(u,v),swap(fu,fv);
  118. update(1,tid[fu],tid[u],w);
  119. u=fa[fu];
  120. fu=top[u];
  121. }
  122. if(dep[u]<dep[v])swap(u,v);
  123. update(1,tid[v],tid[u],w);
  124. }
  125. int solve(int u,int v)
  126. {
  127. int ans=0,fu=top[u],fv=top[v];
  128. int preul=-1,preur=-1,prevl=-1,prevr=-1;
  129. int nowul=-1,nowur=-1,nowvl=-1,nowvr=-1;
  130. while(fu!=fv)
  131. {
  132. if(dep[fu]>dep[fv])
  133. {
  134. ans+=query(1,tid[fu],tid[u],nowul,nowur);
  135. if(nowur==preul&&preul!=-1)ans--;
  136. preul=nowul;preur=nowur;
  137. u=fa[fu];
  138. fu=top[u];
  139. }
  140. else
  141. {
  142. ans+=query(1,tid[fv],tid[v],nowvl,nowvr);
  143. if(nowvr==prevl&&prevl!=-1)ans--;
  144. prevl=nowvl;prevr=nowvr;
  145. v=fa[fv];
  146. fv=top[v];
  147. }
  148. }
  149. if(dep[u]>dep[v])
  150. {
  151. ans+=query(1,tid[v],tid[u],nowul,nowur);
  152. if(nowur==preul&&preul!=-1)ans--;
  153. if(nowul==prevl&&prevl!=-1)ans--;
  154. }
  155. else
  156. {
  157. ans+=query(1,tid[u],tid[v],nowvl,nowvr);
  158. if(nowvr==prevl&&prevl!=-1)ans--;
  159. if(nowvl==preul&&preul!=-1)ans--;
  160. }
  161. return ans;
  162. }
  163. int main()
  164. {
  165. int u,v,w;
  166. char s[5];
  167. scanf("%d%d",&n,&m);
  168. for(int i=1;i<=n;i++)scanf("%d",&a[i]);
  169. for(int i=1;i<n;i++)
  170. {
  171. scanf("%d%d",&u,&v);
  172. ve[u].push_back(v);
  173. ve[v].push_back(u);
  174. }
  175. memset(son,-1,sizeof(son));
  176. dfs1(1,0,0);
  177. dfs2(1,1);
  178. build(1,1,n);
  179. while(m--)
  180. {
  181. scanf("%s%d%d",s,&u,&v);
  182. if(s[0]=='C')
  183. {
  184. scanf("%d",&w);
  185. change(u,v,w);
  186. }
  187. else printf("%d\n",solve(u,v));
  188. }
  189. return 0;
  190. }

  

bzoj-2243 2243: [SDOI2011]染色(树链剖分)的更多相关文章

  1. BZOJ 2243: [SDOI2011]染色 [树链剖分]

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

  2. Bzoj 2243: [SDOI2011]染色 树链剖分,LCT,动态树

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

  3. BZOJ 2243: [SDOI2011]染色 树链剖分 倍增lca 线段树

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/pr ...

  4. BZOJ 2243: [SDOI2011]染色 树链剖分+线段树区间合并

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

  5. BZOJ 2243: [SDOI2011]染色 (树链剖分+线段树合并)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2243 树链剖分的点剖分+线段树.漏了一个小地方,调了一下午...... 还是要细心啊! 结 ...

  6. [bzoj 2243]: [SDOI2011]染色 [树链剖分][线段树]

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

  7. 2243: [SDOI2011]染色(树链剖分+线段树)

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

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

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

  9. POJ 2243 [SDOI2011]染色 | 树链剖分+线段树

    原题链接 肯定是树链剖分的题啦 树剖怎么做可以看我上一篇博客 如果我们已经剖完了: 然后考虑怎么维护重链和查询 用线段树维护的时候当前区间的区间颜色个数应该等于左儿子+右儿子,但是当左儿子的右端点和右 ...

随机推荐

  1. Jquery中的日历插件

    这个插件很简单:只需要在HTML代码中引入插件如下,CLASS名和click事件函数固定! <!doctype html> <html lang="en"> ...

  2. [deviceone开发]-do_SlideListView的简单示例

    一.简介 利用提供的SlideListVIew实现那种cell可以滑动露出底部按钮的功能 主要组件:do_slidelistview 二.效果图 三.相关讨论 http://bbs.deviceone ...

  3. JavaScript中with语句的理解

    with语句的作用是暂时改变作用域链.减少的重复输入. 其语法结构为: with(object){ //statements } 举一个实际例子吧: with(document.forms[0]){ ...

  4. DevExtreme官方视频教程分享

    收集在此,希望对使用这个工具的人有帮助 DevExtreme 1 2 3 4 5 6 DevExpress DevExtreme入门视频一:Getting Started DevExpress Dev ...

  5. 使用Autodesk OAuth服务在用户认证的示例

    大家知道以Autodesk 360为核心的Autodesk 云服务已经陆续发布,ReCap API.InfraWorks API和PLM 360 REST API已经开始的Pilot项目供第三方开发者 ...

  6. git 设置 key 到服务器,同步代码不需要输入用户名和密码

    1  ssh-keygen -t rsa 2  vim ~/.ssh/id_rsa.pub 3. 添加到git 服务器,这样同步代码就不需要输入密码

  7. 防止IOS6与IOS7图标不一致

    点击AppIcon在属性栏内找到iOS icon is pre-rendered打上勾. 如果之前已经安装过,需要先把APP卸载掉再安装.(因为模拟器有缓存) xcode4版本的话需要在INFO内增加 ...

  8. 利用听云Server和听云Network实测Kubernetes和Mesos在高并发下的网络性能

    文章出自:听云博客 随着公司业务的不断增长,我们的应用数量也有了爆发式增长.伴随着应用爆发式的增长,管理的难度也随之加大.如何在业务爆发增长的同时快速完成扩容成了很大的挑战.Docker的横空出世恰巧 ...

  9. 【读书笔记】iOS-程序进入到后台

    当一个iOS应用被送到后台,它的主线程会被暂停.你用NSThread的detachNewThreadSelector:toTar get:withObject:类方法创建的线程也被挂起了.如果你想在后 ...

  10. iOS手势的传递问题

    昨天在做一个页面的时候,我先在一个uiview上面画了一个字母的索引表,之后我通过touchbegan来表示 点击到字母的效果,主要效果是跳出一个界面来显示你按到的字母是什么. 之后我用touchmo ...