对于每个点维护两棵线段树$T1[x],T2[x]$:

$T1[x]$维护$x$子树内,深度在$[l,r]$内的点数,同种颜色有多个的话,保留深度最小的那个。

$T2[x]$维护$x$子树内每种颜色的最小深度。

从底向上合并线段树,先合并$T1$,然后合并$T2$的时候,发现有重复点,那么在$T1$里删去深度大的那个,查询直接在$T1$里区间求和即可。

时间复杂度$O((n+m)\log n)$。

#include<cstdio>
const int N=100010,M=10000000;
int Case,n,m,i,x,y,ans,a[N],f[N],d[N],T1[N],T2[N],tot,l[M],r[M],v[M];
int ins(int x,int a,int b,int c,int p){int y=++tot;v[y]=v[x]+p;if(a==b)return y;int mid=(a+b)>>1;if(c<=mid)l[y]=ins(l[x],a,mid,c,p),r[y]=r[x];else l[y]=l[x],r[y]=ins(r[x],mid+1,b,c,p);return y;
}
int merge1(int x,int y,int a,int b){if(!x||!y)return x+y;int z=++tot;v[z]=v[x]+v[y];if(a==b)return z;int mid=(a+b)>>1;l[z]=merge1(l[x],l[y],a,mid);r[z]=merge1(r[x],r[y],mid+1,b);return z;
}
int merge2(int x,int y,int a,int b,int p){if(!x||!y)return x+y;int z=++tot;if(a==b){if(v[x]<v[y])v[z]=v[x],T1[p]=ins(T1[p],1,n,v[y],-1);else v[z]=v[y],T1[p]=ins(T1[p],1,n,v[x],-1);return z;}int mid=(a+b)>>1;l[z]=merge2(l[x],l[y],a,mid,p);r[z]=merge2(r[x],r[y],mid+1,b,p);return z;
}
int ask(int x,int a,int b,int d){if(b<=d)return v[x];int mid=(a+b)>>1,t=ask(l[x],a,mid,d);if(d>mid)t+=ask(r[x],mid+1,b,d);return t;
}
int main(){scanf("%d",&Case);while(Case--){scanf("%d%d",&n,&m);for(i=1;i<=n;i++)scanf("%d",&a[i]);for(i=2;i<=n;i++)scanf("%d",&f[i]);for(i=1;i<=n;i++)d[i]=d[f[i]]+1;for(i=1;i<=n;i++){T1[i]=ins(0,1,n,d[i],1);T2[i]=ins(0,1,n,a[i],d[i]);}for(i=n;i>1;i--){T1[f[i]]=merge1(T1[f[i]],T1[i],1,n);T2[f[i]]=merge2(T2[f[i]],T2[i],1,n,f[i]);}while(m--){scanf("%d%d",&x,&y);x^=ans,y^=ans;y+=d[x];if(y>n)y=n;printf("%d\n",ans=ask(T1[x],1,n,y));}ans=tot=0;}return 0;
}

  

HDU5709 : Claris Loves Painting相关推荐

  1. HDU5709 Claris Loves Painting

    题目 建两棵动态开点权值线段树. 一棵以颜色为下标,维护每种颜色出现的最浅深度. 一棵以深度为下标,维护以该深度为最浅深度的颜色有多少种. 然后dfs的时候启发式合并线段树即可. #include&l ...

  2. [HDU5709]Claris Loves Painting

    vjudge description 给定一棵\(n\)点的树,每个节点上有一个颜色,每次询问一个点的子树中与这个点距离不超过\(d\)的点的颜色有多少种.强制在线. sol 对每个点开两棵线段树,一 ...

  3. HDU - 5709 Claris Loves Painting 线段树动态开点+合并

    题目链接:https://cn.vjudge.net/problem/HDU-5709 题意:给定一棵n点的树,每个节点上有一个颜色,每次询问一个点的子树中与这个点距离不超过d的点的颜色有多少种 题解 ...

  4. 5709 - Claris Loves Painting

    给定一棵树,树上每个节点有一个颜色,每次询问以x节点为根的子树,深度小于等于d的部分共有几种颜色. 以下摘自胡主力的ppt: 先考虑一个弱化版,询问是询问一个结点的整棵子树的颜色数 先处理出树的dfs ...

  5. hdu5709-Claris Loves Painting【线段树合并】

    正题 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5709 题目大意 nnn个点的一棵树,每次有询问(u,k)(u,k)(u,k)表在uuu的子树中, ...

  6. 巴卡斯杯 中国大学生程序设计竞赛 - 女生专场(重现)解题思路

    此文章可以使用目录功能哟↑(点击上方[+]) 经过这么一次女生赛,告诉我们千万不要小瞧女生,不然会死得很惨,orz... 链接→"巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场( ...

  7. stcoder Splatter Painting 记忆化搜索

    5647: Splatter Painting 时间限制: 2 Sec  内存限制: 256 MB 提交: 32  解决: 16 [提交] [状态] [讨论版] [命题人:admin] 题目描述 Sq ...

  8. AtCoder2362 - Splatter Painting - DFS+思维

    1.题目描述: B - Splatter Painting Time limit : 2sec / Memory limit : 256MB Score : 700 points Problem St ...

  9. mysql sql日期截取年月日_sql截取日期/时间的单独部分,比如年、月、日、小时、分钟等等...

    可以使用EXTRACT() 函数.(oracle和mysql都有该函数) 语法: EXTRACT(unit FROM date) date 参数是合法的日期表达式.unit 参数可以是下列的值: YE ...

最新文章

  1. 2022-2028年中国激光玻璃行业市场供需规模及发展趋势研究报告
  2. 一个用PPT画画的程序员
  3. 【网址收藏】IDEA社区版(Community)和付费版(UItimate)的区别
  4. Linux执行shell脚本的四种方式
  5. idea 的lombok安装完不生效的办法
  6. 前端学习(1887)vue之电商管理系统电商系统之通过路由的形式显示用户列表
  7. Java中发邮件的6种方法
  8. 红旗linux 装xp,XP下硬盘安装红旗LINUX
  9. pyltp实体识别_哈工大 PYLTP 安装 排坑指南
  10. 洛谷——P1014 [NOIP1999 普及组] Cantor 表
  11. 【vim入门笔记】基本操作与插件安装
  12. 不要再危言耸听!家用电脑辐射全揭秘
  13. 阿里巴巴Java开发 之 MySQL规约
  14. php 过滤所有空格_php从文本中去除空格、特殊字符的4种情况
  15. 开源GIS-01-开源库的编译
  16. 华三华为设备序列号查看生产日期
  17. linux+qq+输入法下载官网,续:Linux下安装输入法和QQ软件
  18. jasper ireport
  19. Task 2: Word Vectors and Word Senses (附代码)(Stanford CS224N NLP with Deep Learning Winter 2019)
  20. 北理计算机学院接受转专业条件,北京理工大学本科生专业分流、转专业实施细则...

热门文章

  1. dataframe 转rdd java,在pyspark中将RDD转换为Dataframe
  2. c语言写贪吃蛇什么水平_学了一些C语言,也不知道自己学到什么程度,自己想写个贪吃蛇但是写不出来,想看懂下面这个程序,求解释...
  3. [HNOI2013]切糕
  4. java中如何将字符串数组转换成字符串
  5. js基础---object对象
  6. 64位虚拟机安装64位ubuntu出现问题
  7. java 数据结构容器之HashSet
  8. 企业大数据运用实战案例分享
  9. C 判断输入的字符是什么
  10. 【android】TabLayout文字闪烁问题