题目背景

在一个叫做Travian的世界里,生活着各个大大小小的部落。其中最为强大的是罗马、高卢和日耳曼。他们之间为了争夺资源和土地,进行了无数次的战斗。期间诞生了众多家喻户晓的英雄人物,也留下了许多可歌可泣的动人故事。

其中,在大大小小的部落之间,会有一些道路相连,这些道路是Travian世界里的重要枢纽,简单起见,你可以把这些部落与部落之间相连的道路看作一颗树,可见每条道路对于Travian世界的重要程度。有了这些道路,建筑工人就可以通过这些道路进行友好外交啦。

然而,事情并不会像想象的那样美好,由于资源的匮乏,相邻的部落(由一条道路相连的部落)之间经常会发生大大小小的冲突事件,更有甚者,会升级为部落之间的大型战争。

为了避免误伤,每当两个相邻的部落之间发生大型战争之时,这两个部落间的道路是不允许通行的,对于一些强大的部落,甚至能与多个相邻的部落同时开战,同样的,这些战争地带的道路十分危险,是不可通行的。

天下之势,分久必合,当两个部落经历了不打不相识的苦战之后,他们可以签订停战协议(暂时停战,以后依旧可能再次开战),这样,两个部落之间的道路又会重新恢复为可通行状态,建筑工人们又可以经过此地购买最新的大本营设计图纸来强大自己的部落了。

为了简单起见,我们把各大战争事件按发起的时间顺序依次编号(最先发起的战争编号就为 1,第二次战争编号就为 2,以此类推),当两个部落停战之时,则会直接告诉你这场战争的编号,然后这场战争就载入了史册,不复存在了,当然,这并不会影响到其他战争的编号。

建筑工人十分讨厌战争,因为战争,想从一个部落到另一个部落进行友好交流的建筑工人可能就此白跑一趟。所以,在他们出发之前,都会向你问问能不能到达他们想去的部落。

题目描述

简单起见,你就是要处理下面三件事,所有的事件都是按照时间顺序给出的。

1.( QQ pp qq )从第 pp 个部落出发的建筑工人想知道能否到达第 qq 个部落了,你要回答的便是(Yes/No),注意大小写

2.( CC pp qq )第 pp 个部落与第 qq 个部落开战了,保证他们一定是相邻的部落,且目前处于停战(未开战)状态

3.( UU xx ) 第 xx 次发生的战争结束了,它将永远的被载入史册,不复存在(保证这个消息不会告诉你多次)

输入输出格式

输入格式:

第一行两个数 nn 和 mm , nn 代表了一共有 nn 个部落, mm 代表了以上三种事件发生的总数

接下来的 n - 1n−1 行,每行两个数 pp , qq ,代表了第 pp 个部落与第 qq 个部落之间有一条道路相连

接下来的 mm 行,每行表示一件事,详见题目描述

输出格式:

每行一个“ YesYes ”或者“ NoNo ”,表示从第 pp 个部落出发的建筑工人能否到达第 qq 个部落

输入输出样例

输入样例#1: 复制

  1. 5 9
  2. 1 2
  3. 2 3
  4. 3 4
  5. 4 5
  6. Q 1 4
  7. C 2 1
  8. C 4 3
  9. Q 3 1
  10. Q 1 5
  11. U 1
  12. U 2
  13. C 4 3
  14. Q 3 4
输出样例#1: 复制

  1. Yes
  2. No
  3. No
  4. No
输入样例#2: 复制

  1. 10 10
  2. 1 2
  3. 1 3
  4. 3 4
  5. 3 5
  6. 1 6
  7. 3 7
  8. 1 8
  9. 2 9
  10. 5 10
  11. C 8 1
  12. Q 6 1
  13. C 2 1
  14. Q 2 10
  15. U 1
  16. C 9 2
  17. C 7 3
  18. U 3
  19. Q 6 7
  20. Q 1 10
输出样例#2: 复制

  1. Yes
  2. No
  3. No
  4. Yes
输入样例#3: 复制

  1. 20 20
  2. 1 2
  3. 1 3
  4. 2 4
  5. 1 5
  6. 1 6
  7. 4 7
  8. 1 8
  9. 2 9
  10. 5 10
  11. 1 11
  12. 2 12
  13. 7 13
  14. 1 14
  15. 1 15
  16. 11 16
  17. 4 17
  18. 3 18
  19. 18 19
  20. 8 20
  21. Q 13 5
  22. C 14 1
  23. C 16 11
  24. U 1
  25. U 2
  26. C 20 8
  27. Q 7 1
  28. C 7 4
  29. Q 17 17
  30. Q 1 6
  31. C 16 11
  32. C 2 1
  33. Q 16 2
  34. U 3
  35. U 5
  36. U 6
  37. C 2 1
  38. C 6 1
  39. C 13 7
  40. C 11 1
输出样例#3: 复制

  1. Yes
  2. Yes
  3. Yes
  4. Yes
  5. No

说明

对于30%的数据 1<=n,m<=6000

对于另30%的数据,保证部落之间的地理关系是一条链,且 i 与 i + 1 之间有一条道路

对于另30%的数据,1<=n,m<=100000

对于100%的数据,1<=n,m<=300000

题解

话说没想到这题思路这么妙我居然没想到orz

个人理解:可以将树进行括号表示,用树剖+树状数组可以维护,同时可以求出某一个点的深度

如果某一条边断了,在树状数组上把深度更深的点的括号表示的影响消去

这样的话,同时用深度查询和括号序列查询两点之间的距离,因为断边的影响已被消去,所以如果路径上有断边,二者的查询结果必不相同

于是可以判断能否到达了

  1. //minamoto
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. #define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
  5. char buf[<<],*p1=buf,*p2=buf;
  6. inline int read(){
  7. #define num ch-'0'
  8. char ch;bool flag=;int res;
  9. while(!isdigit(ch=getc()))
  10. (ch=='-')&&(flag=true);
  11. for(res=num;isdigit(ch=getc());res=res*+num);
  12. (flag)&&(res=-res);
  13. #undef num
  14. return res;
  15. }
  16. char obuf[<<],*o=obuf;
  17. inline void print(int x){
  18. x?(*o++='Y',*o++='e',*o++='s'):(*o++='N',*o++='o');
  19. *o++='\n';
  20. }
  21. const int N=;
  22. int st[N],h,ls[N],rs[N],ver[N<<],Next[N<<],head[N],tot,s[N<<],cnt,n,m;
  23. inline void add(int p,int c){
  24. for(int i=p;i<=n<<;i+=i&(-i)) s[i]+=c;
  25. }
  26. inline int sum(int p){
  27. int res=;
  28. for(int i=p;i;i-=i&(-i)) res+=s[i];
  29. return res;
  30. }
  31. inline void add_(int u,int v){
  32. ver[++tot]=v,Next[tot]=head[u],head[u]=tot;
  33. ver[++tot]=u,Next[tot]=head[v],head[v]=tot;
  34. }
  35. int sz[N],fa[N],son[N],dep[N],top[N];
  36. void dfs(int u,int f){
  37. sz[u]=,dep[u]=dep[fa[u]]+;
  38. for(int i=head[u];i;i=Next[i]){
  39. int v=ver[i];
  40. if(v==f) continue;
  41. fa[v]=u;
  42. dfs(v,u);
  43. sz[u]+=sz[v];
  44. if(!son[u]||sz[v]>sz[son[u]]) son[u]=v;
  45. }
  46. }
  47. void dfs(int u){
  48. if(!top[u]) top[u]=u;
  49. ls[u]=++cnt;
  50. if(son[u]) top[son[u]]=top[u],dfs(son[u]);
  51. for(int i=head[u];i;i=Next[i]){
  52. int v=ver[i];
  53. if(v==fa[u]||v==son[u]) continue;
  54. dfs(v);
  55. }
  56. rs[u]=++cnt;
  57. }
  58. int LCA(int x,int y){
  59. while(top[x]!=top[y])
  60. dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];
  61. return dep[x]<dep[y]?x:y;
  62. }
  63. int main(){
  64. //freopen("testdata.in","r",stdin);
  65. n=read(),m=read();
  66. for(int i=;i<n;++i){
  67. int u=read(),v=read();add_(u,v);
  68. }
  69. dfs(n>>,),dfs(n>>);
  70. for(int i=;i<=n;++i) add(ls[i],),add(rs[i],-);
  71. while(m--){
  72. char ch;
  73. while((ch=getc())!='C'&&ch!='Q'&&ch!='U');
  74. switch(ch){
  75. case 'Q':{
  76. int a=read(),b=read();
  77. int lca=LCA(a,b);
  78. int d=dep[a]+dep[b]-*dep[lca];
  79. int dd=sum(ls[a])+sum(ls[b])-*sum(ls[lca]);
  80. print(d==dd);
  81. break;
  82. }
  83. case 'C':{
  84. int a=read(),b=read();
  85. dep[b]>dep[a]?a=b:;
  86. st[++h]=a;
  87. add(ls[a],-),add(rs[a],);
  88. break;
  89. }
  90. case 'U':{
  91. int a=read();
  92. a=st[a];
  93. add(ls[a],),add(rs[a],-);
  94. break;
  95. }
  96. }
  97. }
  98. fwrite(obuf,o-obuf,,stdout);
  99. return ;
  100. }

P3950 部落冲突的更多相关文章

  1. lupgu P3950 部落冲突

    题目链接 luogu P3950 部落冲突 题解 树剖线段树可以 lct还行 代码 #include<cstdio> #include<algorithm> inline in ...

  2. 洛谷 P3950 部落冲突 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例1 输出样例1 输入样例2 输出样例2 输入样例3 输出样例3 说明 思路 AC代码 总结 题面 题目链接 P3 ...

  3. 洛谷P3950 部落冲突 [LCT]

    题目传送门 部落冲突 格式难调,体面就不放了. 分析: julao们应该都看得出来就是个$LCT$板子,战争就$cut$,结束就$link$,询问就$find$.没了... 太久没打$LCT$,然后发 ...

  4. 【刷题】洛谷 P3950 部落冲突

    题目背景 在一个叫做Travian的世界里,生活着各个大大小小的部落.其中最为强大的是罗马.高卢和日耳曼.他们之间为了争夺资源和土地,进行了无数次的战斗.期间诞生了众多家喻户晓的英雄人物,也留下了许多 ...

  5. 【luogu P3950 部落冲突】 题解

    题目连接:https://www.luogu.org/problemnew/show/P3950 1.像我这种学数据结构学傻了的 2.边权化点权 所有点权初始化0 3.对于战争 将深度较深的-1,对于 ...

  6. P3950部落冲突

    题面 \(Solution:\) 法一:LCT裸题 又好想又好码,只不过常数太大. 法二:树链剖分 每次断边将该边权的值++,连边--,然后边权化点权(给儿子),询问就查询从x到y的路径上的边权和,树 ...

  7. 【Luogu】P3950部落冲突(树链剖分)

    题目链接 状态奇差无比,sbt都能错一遍. 不动笔光想没有想到怎么做,画图之后发现一个很明显的性质…… 那就是两个开战的部落,其中一个是另一个的父亲. 所以在儿子那里加个权值.查询的时候树链剖分查询链 ...

  8. 洛谷:P3950 部落冲突

    原题地址:https://www.luogu.org/problemnew/show/P3950 题目简述 给定一棵树,每次给定一个操作,有如下两种: 将某条边染黑 2.询问给定的u,v两点间是否有边 ...

  9. luogu题解 P3950部落冲突--树链剖分

    题目链接 https://www.luogu.org/problemnew/show/P3950 分析 大佬都用LCT,我太弱只会树链剖分 一个很裸的维护边权树链剖分题.按照套路,对于一条边\(< ...

随机推荐

  1. Specular Mask Texture

    [Specular Mask Texture] Specular Texture是一个Mask纹理,通过Mask纹理的texel可以控制每个像素的纹理. 在属性中添加Specular Mask Tex ...

  2. 【BZOJ3238】差异【后缀自动机+dp】

    题意 分析 这个题目还是很优秀的.sigma(len(Ti)+len(Tj))的值是一定的=n*(n+1)*(n-1)/2.那么关键就是求任意两个后缀的lcp的和了. 我们怎么求两个后缀的lcp?如果 ...

  3. 从计算框架MapReduce看Hadoop1.0和2.0的区别

    一.1.0版本 主要由两部分组成:编程模型和运行时环境. 编程模型为用户提供易用的编程接口,用户只需编写串行程序实现函数来实现一个分布式程序,其他如节点间的通信.节点失效,数据切分等,则由运行时环境完 ...

  4. C#中不同格式数据校验的正则表达式

    网上经常看到用正则表达式校验数据的文章,有的虽然总结得很全,但是大多数都没有经过严格验证,错误较多. 本文包含三十余条不同格式数据校验的C#正则表达式,一般均附有说明,且在Visual Studio里 ...

  5. 1.在VC编译器下面为什么每个头文件以及源文件都要包含“stdAfx.h”,那么stdAfx.h中到底存放了什么,用来做什么?

    我们知道在windows平台下面很多的文件后缀名中都含有Afx,其实Afx是微软公司的一个技术研发团队名称,vc下的“stdAfx.h”和“stdAfx.cpp”文件就是有他们所研发出来的,为什么要这 ...

  6. jquery设置select选中的文本

    <select id="prov">  <option value="1">北京市</option>  <option ...

  7. Mockplus设计大赛获奖选手专访 | Intimate:你的专属密友音乐播放器

    “Intimate中文意思是密友,就是想让这个音乐APP成为最懂用户的一款软件.” 如果,你随身听的音乐APP,可以成为知你懂你的密友,你幸福,她清唱一首<小幸运>:你悲伤,她低声浅吟&l ...

  8. Spring获取HttpServletRequest对象

    <!-- WEB.XML中配置相关的监听机制 -->  <listener>   <listener-class>  org.springframework.web ...

  9. Session分布式共享 = Session + Redis + Nginx(转)

    出处:http://www.cnblogs.com/newP/p/6518918.html 一.Session 1.Session 介绍 我相信,搞Web开发的对Session一定再熟悉不过了,所以我 ...

  10. 【转载】Redis优化经验

    转载地址:http://blog.sina.com.cn/s/blog_4be888450100z2ze.html 内存管理优化 Redis Hash是value内部为一个HashMap,如果该Map ...