HDU5709 : Claris Loves Painting
对于每个点维护两棵线段树$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相关推荐
- HDU5709 Claris Loves Painting
题目 建两棵动态开点权值线段树. 一棵以颜色为下标,维护每种颜色出现的最浅深度. 一棵以深度为下标,维护以该深度为最浅深度的颜色有多少种. 然后dfs的时候启发式合并线段树即可. #include&l ...
- [HDU5709]Claris Loves Painting
vjudge description 给定一棵\(n\)点的树,每个节点上有一个颜色,每次询问一个点的子树中与这个点距离不超过\(d\)的点的颜色有多少种.强制在线. sol 对每个点开两棵线段树,一 ...
- HDU - 5709 Claris Loves Painting 线段树动态开点+合并
题目链接:https://cn.vjudge.net/problem/HDU-5709 题意:给定一棵n点的树,每个节点上有一个颜色,每次询问一个点的子树中与这个点距离不超过d的点的颜色有多少种 题解 ...
- 5709 - Claris Loves Painting
给定一棵树,树上每个节点有一个颜色,每次询问以x节点为根的子树,深度小于等于d的部分共有几种颜色. 以下摘自胡主力的ppt: 先考虑一个弱化版,询问是询问一个结点的整棵子树的颜色数 先处理出树的dfs ...
- hdu5709-Claris Loves Painting【线段树合并】
正题 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5709 题目大意 nnn个点的一棵树,每次有询问(u,k)(u,k)(u,k)表在uuu的子树中, ...
- 巴卡斯杯 中国大学生程序设计竞赛 - 女生专场(重现)解题思路
此文章可以使用目录功能哟↑(点击上方[+]) 经过这么一次女生赛,告诉我们千万不要小瞧女生,不然会死得很惨,orz... 链接→"巴卡斯杯" 中国大学生程序设计竞赛 - 女生专场( ...
- stcoder Splatter Painting 记忆化搜索
5647: Splatter Painting 时间限制: 2 Sec 内存限制: 256 MB 提交: 32 解决: 16 [提交] [状态] [讨论版] [命题人:admin] 题目描述 Sq ...
- AtCoder2362 - Splatter Painting - DFS+思维
1.题目描述: B - Splatter Painting Time limit : 2sec / Memory limit : 256MB Score : 700 points Problem St ...
- mysql sql日期截取年月日_sql截取日期/时间的单独部分,比如年、月、日、小时、分钟等等...
可以使用EXTRACT() 函数.(oracle和mysql都有该函数) 语法: EXTRACT(unit FROM date) date 参数是合法的日期表达式.unit 参数可以是下列的值: YE ...
最新文章
- 2022-2028年中国激光玻璃行业市场供需规模及发展趋势研究报告
- 一个用PPT画画的程序员
- 【网址收藏】IDEA社区版(Community)和付费版(UItimate)的区别
- Linux执行shell脚本的四种方式
- idea 的lombok安装完不生效的办法
- 前端学习(1887)vue之电商管理系统电商系统之通过路由的形式显示用户列表
- Java中发邮件的6种方法
- 红旗linux 装xp,XP下硬盘安装红旗LINUX
- pyltp实体识别_哈工大 PYLTP 安装 排坑指南
- 洛谷——P1014 [NOIP1999 普及组] Cantor 表
- 【vim入门笔记】基本操作与插件安装
- 不要再危言耸听!家用电脑辐射全揭秘
- 阿里巴巴Java开发 之 MySQL规约
- php 过滤所有空格_php从文本中去除空格、特殊字符的4种情况
- 开源GIS-01-开源库的编译
- 华三华为设备序列号查看生产日期
- linux+qq+输入法下载官网,续:Linux下安装输入法和QQ软件
- jasper ireport
- Task 2: Word Vectors and Word Senses (附代码)(Stanford CS224N NLP with Deep Learning Winter 2019)
- 北理计算机学院接受转专业条件,北京理工大学本科生专业分流、转专业实施细则...