前言:

题面挺神仙。反正我考试的时候看了40分钟也没看懂。

后来改题感觉自己写的挺假,没想到加个\(k==1\)的特判竟然就A了?无语力。

解析:

看懂题以后就好说了。首先这显然是一个树形结构。我们考虑把“交”的操作放到一棵树上,把“并”的操作放到一棵树上。

考虑建边。比如将\((1,2,3)\)并成\((4)\),那么就在并树上,将\(1,2,3\)的父亲设置成\(4\)。

然后,对于每个询问\((x,y)\),如果在交树上,\(x\)是\(y\)的祖先,或在并树上,\(y\)是\(x\)的祖先,那么答案就是\(1\),否则是\(0\)。

看起来有手就行。不过细节还是要注意。

关于实现上的细节:

1.

我们在建立模型的时候,显然建的是有向边,由儿子指向父亲。但我们在真正建树的时候,是要建无向边。因为无向边比较好维护。那此时怎么判断父子关系呢?

首先,有一个性质。每个节点的父亲的编号一定比自己的编号大。也就是说,大的点一定在上面。因为维护的是一片森林,所以可以根据这个性质找到每棵树的根节点。

所以可以考虑按编号从大到小DFS一遍。按照DFS序判断父子关系。

写过树剖的人都知道,一颗子树内的dfs序是连续的。因此假如y是x的父亲,那么\(dfn[y]<=dfn[x]<=dfn[x]+size[x]-1<=dfn[y]+size[y]-1\)

2.

注意一个细节。\(k==1\)的时候,交和并等价。那么既要在交树上建边,又要在并树上建边。

然后就可以A掉这道题了。

关于正确性:

1.为什么只需要判断x和y的关系,不需要判断y的祖先和x的关系呢?

首先,对于在y到根节点上的路径上的点(不包括根节点),那么这些节点既有入度,也有出度,那么这些点就不可能在另外一棵树上出现了。

其次,对于根节点,它只可能去合成别的节点,那么它在另一棵树上一定没有入度。也就是说,即使根节点在另一棵树上出现,它也必然是叶子节点,不可能是x的父亲,所以不用判。

代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int maxn=500000+10;
  4. int n,m,cntj,cntb,totot,totj,totb,Time;
  5. struct node{
  6. int to,next;
  7. }edgej[maxn],edgeb[maxn];
  8. int headj[maxn],headb[maxn],dfnb[maxn],dfnj[maxn],sizeb[maxn],sizej[maxn];
  9. struct que{
  10. int x,y;
  11. }b[maxn];
  12. bool vis[maxn];
  13. void addj(int from,int to){
  14. edgej[++cntj].to=to;
  15. edgej[cntj].next=headj[from];
  16. headj[from]=cntj;
  17. }
  18. void addb(int from,int to){
  19. edgeb[++cntb].to=to;
  20. edgeb[cntb].next=headb[from];
  21. headb[from]=cntb;
  22. }
  23. void dfs1(int u,int f){
  24. dfnj[u]=++Time;
  25. sizej[u]=1;
  26. vis[u]=1;
  27. for(int i=headj[u];i;i=edgej[i].next){
  28. int v=edgej[i].to;
  29. if(v==f) continue;
  30. dfs1(v,u);
  31. sizej[u]+=sizej[v];
  32. }
  33. }
  34. void dfs2(int u,int f){
  35. dfnb[u]=++Time;
  36. sizeb[u]=1;
  37. vis[u]=1;
  38. for(int i=headb[u];i;i=edgeb[i].next){
  39. int v=edgeb[i].to;
  40. if(v==f) continue;
  41. dfs2(v,u);
  42. sizeb[u]+=sizeb[v];
  43. }
  44. }
  45. int get_ans(int x,int y){
  46. if(dfnj[x]<=dfnj[y]&&dfnj[x]+sizej[x]>=dfnj[y]+sizej[y]) return 1;
  47. if(dfnb[y]<=dfnb[x]&&dfnb[y]+sizeb[y]>=dfnb[x]+sizeb[x]) return 1;
  48. return 0;
  49. }
  50. void Solve(){
  51. scanf("%d%d",&n,&m);
  52. for(int i=1,op,k,ss;i<=m;++i){
  53. scanf("%d",&ss);
  54. if(ss){
  55. totot++;
  56. scanf("%d%d",&b[totot].x,&b[totot].y);
  57. }else{
  58. scanf("%d%d",&op,&k);
  59. if(op){
  60. totb++;
  61. if(k>1){
  62. for(int j=1;j<=k;++j){
  63. scanf("%d",&ss);
  64. addb(ss,totb+totj+n);
  65. addb(totb+totj+n,ss);
  66. }
  67. }else{
  68. for(int j=1;j<=k;++j){
  69. scanf("%d",&ss);
  70. addb(ss,totb+totj+n);
  71. addb(totb+totj+n,ss);
  72. addj(ss,totb+totj+n);
  73. addj(totb+totj+n,ss);
  74. }
  75. }
  76. }else{
  77. totj++;
  78. if(k>1){
  79. for(int j=1;j<=k;++j){
  80. scanf("%d",&ss);
  81. addj(ss,totj+totb+n);
  82. addj(totj+totb+n,ss);
  83. }
  84. }else{
  85. for(int j=1;j<=k;++j){
  86. scanf("%d",&ss);
  87. addb(ss,totb+totj+n);
  88. addb(totb+totj+n,ss);
  89. addj(ss,totb+totj+n);
  90. addj(totb+totj+n,ss);
  91. }
  92. }
  93. }
  94. }
  95. }
  96. //printf("n==%d totj=%d totb=%d cntj==%d cntb==%d\n",n,totj,totb,cntj,cntb);
  97. for(int i=totj+totb+n;i;--i) if(!vis[i]) dfs1(i,0);
  98. memset(vis,0,sizeof(vis));
  99. Time=0;
  100. for(int i=totb+totj+n;i;--i) if(!vis[i]) dfs2(i,0);
  101. //for(int i=1;i<=totj+totb+n;++i) printf("dfnj[%d]=%d dfnb[%d]=%d sizej[%d]=%d sizeb[%d]=%d\n",i,dfnj[i],i,dfnb[i],i,sizej[i],i,sizeb[i]);
  102. for(int i=1;i<=totot;++i) printf("%d\n",get_ans(b[i].x,b[i].y));
  103. }
  104. int main(){
  105. freopen("friendship.in","r",stdin);
  106. freopen("friendship.out","w",stdout);
  107. Solve();
  108. return 0;
  109. }

主仆见证了 Hobo 的离别 题解的更多相关文章

  1. NOIP模拟测试26「嚎叫响彻在贪婪的机房·主仆见证了 Hobo 的离别·征途堆积出友情的永恒」

    题目比较神仙,注意是题目神仙 贪婪暗示贪心,堆积暗示堆优化$\%\%\%\%\%\%\%$ 两个乱搞$+$一个堆优化$dp$ 嚎叫响彻在贪婪的机房 题解 对于一个序列来说只要他们差的$gcd$不为$1 ...

  2. 8.19 NOIP模拟测试26(B) 嚎叫响彻在贪婪的厂房+主仆见证了 Hobo 的离别+征途堆积出友情的永恒

    T1 嚎叫响彻在贪婪的厂房 以前做过一个等比数列的题「序列」,这个类似 是等差数列且公差不为1的条件就是各项差的绝对值的$gcd!=1$,每次拿出序列前两个数,求出差值,插入到set里,每次向后扩展, ...

  3. HZOI20190819模拟26题解

    题面:https://www.cnblogs.com/Juve/articles/11376806.html A. 嚎叫响彻在贪婪的厂房: 是时候学习一下map和set的用法了...... 贪心:区间 ...

  4. HZOJ 20190819 NOIP模拟26题解

    考试过程: 照例开题,然后觉得三道题都挺难,比昨天难多了(flag×1),T1 dp?T2 数据结构? T3 dp?事实证明我是sb然后决定先搞T2,但是,woc,这题在说什么啊,我怎么看不懂题啊,连 ...

  5. 「模拟8.19 A嚎叫..(set) B主仆..(DFS) C征程..(DP+堆优化)」

    为啥这一套题目背景感到很熟悉. T1  嚎叫响彻在贪婪的厂房 考试一个小时没调出来,自闭了.......... 正解很好想,最后实在打不出来了只好暴力骗分了... 联想到以前做的题:序列(涉及质因数分 ...

  6. Noip模拟77 2021.10.15

    T1 最大或 $T1$因为没有开$1ll$右移给炸掉了,调了一年不知道为啥,最后实在不懂了 换成$pow$就过掉了,但是考场上这题耽误了太多时间,后面的题也就没办法好好打了.... 以后一定要注意右移 ...

  7. NOIP 模拟 七十七

    100+60+95+30; T4 一个变量打错挂了40.. T1 最大或 考虑从高到低枚举的二进制位,然后和的对应二进制位进行比较.如果两 者相同,那么不论怎么选择,,答案在这个位置上的值一定和在这个 ...

  8. NOIP模拟77

    前言 感觉最近太飘了,这次考试是挺好的一次打击(好像也不算是). 犯了一个智障错误(双向边一倍数组 100pts->30pts)别的就.. T1 最大或 解题思路 一开始我以为是一个找规律,然而 ...

  9. 2021.10.15考试总结[NOIP模拟77]

    \(n=40\)考虑\(meet \;in \;the \;middle\) 某个元素有关的量只有一个时考虑转化为树上问题 对暴力有自信,相信数据有梯度 没了 UPD:写了个略说人话的. T1 最大或 ...

随机推荐

  1. VueJS学习资料大全

    参考:http://www.worktle.com/articles/2467/ 文档&社区 Vue.js官方网站(中文) :http://cn.vuejs.org/ Vue论坛:http:/ ...

  2. SprinBoot-SpringData-整合

    目录 SpringData 整合JDBC JDBCTemplate 整合Druid 配置数据源 配置Druid数据源监控 整合MyBatis 整合测试 整合Redis 测试整合 序列化配置 自定义re ...

  3. python库--pandas--Series.str--字符串处理

    原数据 import pandas as pd a = pd.Series(['aSd', 'asd', 'dfd fsAsf sfs']) b = pd.Series([None, 'asd', ' ...

  4. ysoserial payloads/JRMPClient

    ysoserial payloads/JRMPClient 环境:JDK8u102 payloads/JRMPClient可以配合exploit/JRMPListener模块来使用 1.在自己服务器上 ...

  5. mysql中通过sql语句查询指定数据表的字段信息

      mysql数据库在安装完成时,自动创建了information_schema.mysql.test这三个数据库.其中,information_schema记录了创建的所有数据库的相关信息,因此可以 ...

  6. HCNP Routing&Switching之路由过滤工具Filter-Policy

    前文我们了解了路由控制技术中路由策略和路由匹配工具IP-Prefix相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/15314262.html:今天我们 ...

  7. 简单学习PHP中的层次性能分析器

    在 PHP 中,我们需要进行调试的时候,一般都会使用 memory_get_usage() 看下内存的使用情况.但如果想看当前的脚本 CPU 的占用情况就没有什么现成的函数了.不过,PHP 也为我们提 ...

  8. PHP操作用户提交内容时需要注意的危险函数

    对于我们的程序开发来说,用户的输入是解决安全性问题的第一大入口.为什么这么说呢?不管是SQL注入.XSS还是文件上传漏洞,全部都和用户提交的输入参数有关.今天我们不讲这些问题,我们主要探讨下面对用户的 ...

  9. Shell系列(6)- 管道符

    多命令顺序执行 多命令执行符 格式 作用 ; 命令1 ; 命令2 连接命令:多个命令顺序执行,命令之间没有任何逻辑联系:前面命令报错,后面命令照常执行 && 命令1 && ...

  10. 常用的word技巧

    自动生成标题 自动生成目录 显示导航列 修订 查看最终版本