BZOj #4771. 七彩树(主席树+dfn序+lca)

BZOj #4771. 七彩树

  • description
  • solution
  • code

description

给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点。每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i]。如果c[i]=c[j],那么我们认为点i和点j拥有相同的颜色。定义depth[i]为i节点与根节点的距离,为了方便起见,你可以认为树上相邻的两个点之间的距离为1。站在这棵色彩斑斓的树前面,你将面临m个问题。

每个问题包含两个整数x和d,表示询问x子树里且depth不超过depth[x]+d的所有点中出现了多少种本质不同的颜色。请写一个程序,快速回答这些询问。

Input

第一行包含一个正整数T(1<=T<=500),表示测试数据的组数。

每组数据中,第一行包含两个正整数n(1<=n<=100000)和m(1<=m<=100000),表示节点数和询问数。

第二行包含n个正整数,其中第i个数为c[i](1<=c[i]<=n)c[i](1<=c[i]<=n)c[i](1<=c[i]<=n),分别表示每个节点的颜色。

第三行包含n-1个正整数,其中第i个数为f[i+1](1<=f[i]<i)f[i+1](1<=f[i]<i)f[i+1](1<=f[i]<i),表示节点i+1的父亲节点的编号。

接下来m行,每行两个整数x(1<=x<=n)和d(0<=d<n),依次表示每个询问。

输入数据经过了加密,对于每个询问,如果你读入了x和d,那么真实的x和d分别是x xor last和d xor last,

其中last表示这组数据中上一次询问的答案,如果这是当前数据的第一组询问,那么last=0。

输入数据保证n和m的总和不超过500000。

Output

对于每个询问输出一行一个整数,即答案。

Sample Input

1
5 8
1 3 3 2 2
1 1 3 3
1 0
0 0
3 0
1 3
2 1
2 0
6 2
4 1

Sample Output

1
2
3
1
1
2
1
1

solution

询问子树内的问题,通常都转化成dfn序,然后就可以用线段树维护,变成区间问题

询问距离不超过depx+ddep_x+ddepx+d,那就按深度排序后,建主席树

则对于深度为iii的版本的线段树只会存在深度≤i\le ii的点

线段树上的点管辖的区间就是其子树

其点存的值,就是管辖区间内不同颜色的个数

最后只需要处理子树内多个点有同样颜色的修改

具体而言,根据dfn序,对于新增点iii,在线段树上对应的点进行+1

找到与其颜色相同的dfn小于iii的最大dfn序对应的点,记为iii的前驱

那么求出这两个点的lca,从lca往上的点都含有这两个点,但只需要算一个,所以在线段树上lca对应的叶子节点,进行-1

同理。找到与其颜色相同的dfn大于iii的最小dfn序对应的点,记为iii的后继

那么求出这两个点的lca,从lca往上的点都含有这两个点,但只需要算一个,所以在线段树上lca对应的叶子节点,进行-1

但是前驱和后继的lca又多减了111,所以要对其进行+1操作

code

#include <set>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 100005
set < int > s[maxn];
struct node { int id, dep; }t[maxn];
int T, n, m, cnt;
int root[maxn], c[maxn], dep[maxn], dfn[maxn], St[maxn], Ed[maxn], mp[maxn], head[maxn], to[maxn], nxt[maxn];
int f[maxn][20];void dfs( int u ) {dep[u] = dep[f[u][0]] + 1;dfn[u] = St[u] = ++ cnt;mp[cnt] = u;for( int i = 1;i < 20;i ++ )f[u][i] = f[f[u][i - 1]][i - 1];for( int i = head[u];i;i = nxt[i] ) dfs( to[i] );Ed[u] = cnt;
}struct Node { int lson, rson, sum; }tree[maxn * 50];void modify( int &now, int lst, int l, int r, int pos, int k ) {tree[now = ++ cnt] = tree[lst];tree[now].sum += k;if( l == r ) return;int mid = ( l + r ) >> 1;if( pos <= mid ) modify( tree[now].lson, tree[lst].lson, l, mid, pos, k );else modify( tree[now].rson, tree[lst].rson, mid + 1, r, pos, k );
}int query( int now, int l, int r, int L, int R ) {if( r < L or R < l ) return 0;if( L <= l and r <= R ) return tree[now].sum;int mid = ( l + r ) >> 1;return query( tree[now].lson, l, mid, L, R ) + query( tree[now].rson, mid + 1, r, L, R );
}int lca( int u, int v ) {if( dep[u] < dep[v] ) swap( u, v );for( int i = 19;~ i;i -- ) if( dep[f[u][i]] >= dep[v] ) u = f[u][i];if( u == v ) return u;for( int i = 19;~ i;i -- ) if( f[u][i] ^ f[v][i] ) u = f[u][i], v = f[v][i];return f[u][0];
}int main() {scanf( "%d", &T );while( T -- ) {scanf( "%d %d", &n, &m );for( int i = 1;i <= n;i ++ )	head[i] = 0, s[i].clear();for( int i = 1;i <= n;i ++ )	scanf( "%d", &c[i] );cnt = 1;for( int i = 2;i <= n;i ++ ) {scanf( "%d", &f[i][0] );to[cnt] = i, nxt[cnt] = head[f[i][0]], head[f[i][0]] = cnt ++;}cnt = 0;dfs( 1 );for( int i = 1;i <= n;i ++ )	t[i].id = i, t[i].dep = dep[i];sort( t + 1, t + n + 1, []( node x, node y ) { return x.dep < y.dep; } );cnt = 0;for( int i = 1;i <= n;i ++ ) {root[t[i].dep] = root[t[i - 1].dep];int id = t[i].id, d = t[i].dep;modify( root[d], root[d], 1, n, dfn[id], 1 );auto it = s[c[id]].lower_bound( dfn[id] );int pre = -1, nxt = -1;if( it != s[c[id]].end() ) {nxt = *it;modify( root[d], root[d], 1, n, dfn[lca( id, mp[nxt] )], -1 );}if( it != s[c[id]].begin() ) {pre = * (-- it);modify( root[d], root[d], 1, n, dfn[lca( id, mp[pre] )], -1 );}if( ~ pre and ~ nxt )modify( root[d], root[d], 1, n, dfn[lca( mp[pre], mp[nxt] )], 1 );s[c[id]].insert( dfn[id] );}int last = 0, x, d;while( m -- ) {scanf( "%d %d", &x, &d );x ^= last, d ^= last;printf( "%d\n", last = query( root[dep[x] + d], 1, n, St[x], Ed[x] ) );}cnt = 0;}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/317061.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

免费馅饼 HDU - 1176

免费馅饼 HDU - 1176 题意&#xff1a; 都说天上不会掉馅饼&#xff0c;但有一天gameboy正走在回家的小径上&#xff0c;忽然天上掉下大把大把的馅饼。说来gameboy的人品实在是太好了&#xff0c;这馅饼别处都不掉&#xff0c;就掉落在他身旁的10米范围内。馅饼如果掉在了地上…

CF1631F:Flipping Range(dp)

解析 设 x,y∈B,x<yx,y\in B,x<yx,y∈B,x<y&#xff0c;那么也有 x−y∈Bx-y\in Bx−y∈B。 递归下去&#xff0c;根据辗转相减求 gcd⁡\gcdgcd 的方法可知&#xff0c;最终会得到 gcd⁡(x,y)\gcd(x,y)gcd(x,y)。 那么对于整个集合 BBB &#xff0c;它也就等价于所有…

微软 HoloLens 2 正式登场!让你看看什么叫真正的黑科技

北京时间 2 月 25 日凌晨消息&#xff0c;微软在 MWC19 举行新品发布会&#xff0c;正式发布了万众期待的 HoloLens 2 等产品。▲ 认识全新的 Microsoft HoloLens 2微软 HoloLens 全息眼镜是微软推出的一款头戴式混合现实装置&#xff0c;可以完全独立使用&#xff0c;无需线缆…

Piggy-Bank HDU - 1114

Piggy-Bank HDU - 1114 题意&#xff1a; 小猪储钱罐存在一个大的问题&#xff0c;即无法确定其中有多少钱。因此&#xff0c;我们可能在打碎小猪储钱罐之后&#xff0c;发现里面的钱不够。显然&#xff0c;我们希望避免这种不愉快的情况。唯一的可能是&#xff0c;称一下小猪…

BZOJ #3166. [Heoi2013]Alo(可持久化trie树+set)

#3166. [Heoi2013]AlodescriptionsolutioncodeBZOJ3166 description Welcome to ALO ( Arithmetic and Logistic Online)。这是一个VR MMORPG &#xff0c; 如名字所见&#xff0c;到处充满了数学的谜题。 现在你拥有n颗宝石&#xff0c;每颗宝石有一个能量密度&#xff0c;记…

洛谷P6054:开门大吉

Description\text{Description}Description P6054 开门大吉 nnn 位选手去参加节目“开门大吉”。共有 mmm 套题&#xff0c;每套题包含 ppp 个题目&#xff0c;第 iii 位选手答对第 jjj 套题中第 kkk 道的概率为 fi,j,kf_{i,j,k}fi,j,k​。 若一位选手答对第 iii 题&#xff0…

Docker最全教程之Ubuntu下安装Docker(十五)

前言Ubuntu是一个以桌面应用为主的开源GNU/Linux操作系统&#xff0c;应用很广。本篇主要讲述Ubuntu下使用SSH远程登录并安装Docker&#xff0c;并且提供了Docker安装的两种方式&#xff0c;希望对大家有所帮助。拥抱Linux&#xff0c;大家可以从Ubuntu开始&#xff01;Ubuntu下…

群论学习笔记

文章目录前言群基本定义&#xff1a;子群陪集拉格朗日定理正规子群交换群商群阶置换定义置换的乘法循环置换群群作用等价类不动点Burnside引理内容证明法1 轨道-稳定子定理法2Polya 定理所谓群论&#xff0c;就是对群体行为问题的讨论。 &#xff08;逃&#xff09; 前言 个人…

Super Jumping! Jumping! Jumping! HDU - 1087

Super Jumping! Jumping! Jumping! HDU - 1087 题意&#xff1a; 给定一条长度为n的序列&#xff0c;其中一定存在一条元素和最大的严格上升子序列&#xff0c;求这条序列的元素和。 题解&#xff1a; 最长上升序列模板题 代码&#xff1a; #include<bits/stdc.h> …

Codeforces Round #727 (Div. 2) 题解

文章目录A. Contest StartB. Love SongC. Stable GroupsD. PriceFixedE. Game with CardsF. Strange Array#727-Div.2A. Contest Start 数学题&#xff0c;分类讨论 一般的&#xff0c;一段区间[l,r][l,r][l,r]会对后面固定人数造成影响&#xff0c;假设是kkk最后kkk个人&…

潘淳(寒树Office):不务正业的公众号满月了,都写了些啥?

三喜临门一 喜今天真是个好日子&#xff0c;“流浪太阳”又回来了&#xff0c;阴雨绵绵长恨无期&#xff0c;今天苏州终于天晴&#xff0c;于是心情大好&#xff01;都说好心情会带来好运气&#xff0c;冥冥感觉要写点啥了&#xff0c;果不其然今天还有另外两喜。大早起来得…

G List it all

传送 题意&#xff1a; 题解&#xff1a; 我们来考虑以下样例&#xff1a;1&#xff0c;1&#xff0c;2 我们先考虑1的贡献&#xff1a;如图(图中只花了) 2&#xff01;表示还剩两个空位&#xff0c;还有两个数未填入&#xff0c;所以是2&#xff01;个 对于n个数重复&#x…

洛谷P4727:图的同构计数(Polya引理)(dfs)

解析 《关于我想了半天 dp 结果看题解 dfs 就行这回事》 我就说 gcd⁡\gcdgcd 这玩意 dp 个锤子啊… 拆分数的增长速度远没有想像中那么大&#xff0c;事实上&#xff0c;n60n60n60 也就 1e6 左右。 据题解说&#xff0c;这玩意的增长速度仅有 O(enn)O(\frac{e^{\sqrt n}}{n})…

ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法

一、前言在非静态页面的项目开发中&#xff0c;必定会涉及到对于数据库的访问&#xff0c;最开始呢&#xff0c;我们使用 Ado.Net&#xff0c;通过编写 SQL 帮助类帮我们实现对于数据库的快速访问&#xff0c;后来&#xff0c;ORM&#xff08;Object Relational Mapping&#x…

Codeforces Round #699 (Div. 2) 题解

文章目录A. Space NavigationB. New ColonyC. Fence PaintingD. AB GraphE. Sorting BooksF. AB Tree#699-Div.2A. Space Navigation 对于最终位置(x,y)&#xff0c;我们只关心那两个方向的字符是否足够即可 #include <cstdio> #include <cstring> #define maxn …

洛谷P4271:New Barns P(倍增)(LCT)(直径)

解析 倍增真香 关键性质&#xff1a;树上距离一个点最远的点必定是直径两端点其一。 本题限制好&#xff0c;要求少动态维护倍增数组暴力维护直径即可。 如果每次合并的是两棵树&#xff0c;而不是一棵树加一个点&#xff0c;可以先离线下来&#xff0c;照样能做。 如果每次强…

HDU 5510 Bazinga

HDU 5510 Bazinga 题意&#xff1a; 依次给你n个字符串&#xff0c;让你找到编号最大的字符串&#xff0c;存在一个比他编号小的字符串且不是其子串 题解&#xff1a; string中有find查找功能&#xff0c; 思路是用一个vector来存之前所有字符串&#xff0c;数组book用来表…

微软发布 Visual Studio 2019年第二季度路线图

微软近日发布了 Visual Studio 2019 年第二季度的路线图&#xff0c;路线图介绍了目前 VS 致力于在 VS 2019 发布的一些重要功能。官方表示&#xff0c;Visual Studio 2019 将继续按照 Visual Studio 发行周期流程提供更新&#xff0c;也就是约每 6 周推出一次次要更新&#xf…

Educational Codeforces Round 107 (Rated for Div. 2) 题解

文章目录A. Review SiteB. GCD LengthC. Yet Another Card DeckD. Min Cost StringE. Colorings and DominoesF. ChainwordG. Chips on a BoardEducational-Round-107A. Review Site 都给了两台机子&#xff0c;直接把所有只会投②的扔到一台&#xff0c;其余的全是另一台 就…

李争——一个骨子里是极客的程序员

我的业余作品《IT 英雄传》&#xff0c;聚焦身边的英雄&#xff0c;以文字采访的形式记录奇人趣事&#xff0c;笑看风云变幻。所写的人都是我见过面且比较熟悉的&#xff0c;绝大部分都是交往很久的&#xff0c;其中为了避嫌&#xff0c;我很少写微软同事&#xff0c;但今天这一…