给定一棵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的所有点中出现了多少种本质不同的颜色
。请写一个程序,快速回答这些询问。

输入

第一行包含一个正整数T(1<=T<=500),表示测试数据的组数。
每组数据中,第一行包含两个正整数n(1<=n<=100000)和m(1<=m<=100000),表示节点数和询问数。
第二行包含n个正整数,其中第i个数为c[i](1<=c[i]<=n),分别表示每个节点的颜色。
第三行包含n-1个正整数,其中第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。

输出

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

样例输入

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

样例输出

1
2
3
1
1
2
1
1
  主席树神题,首先考虑没有深度限制的做法:因为每个点颜色只会对从它到根节点的链上的所有点有贡献,因此可以树上差分把这个点的权值+1,又因为同种颜色dfs序中相邻的点在它们lca到根的路径上贡献算重了,所以在LCA处权值-1。对于每次查询就变成了查询一个点的子树中的权值和,只要找出整棵树的dfs序,架在线段树上查询区间和就行了。但有了深度限制后,线段树上的子树区间需要加到答案里的点就不是连续的一段区间了。但怎么才能消除大于深度限制的点对区间和的影响?只要使他们在查询时为0就行了!那么就可以用可持久化线段树按层建树,什么意思呢?将深度为d的所有点加到第d棵可持久化线段树中,这样每次查询时,线段树中只包含d[x]层到d[x]+dep层的所有点的权值,查询的依旧是x子树区间,但d[x]+dep层以下的点这一时刻权值为0,对答案无影响。但改成按层加权值后还有一个重要的事没有解决,那就是每种颜色的dfs序的树上差分。因为是按层数加点,所以dfs序中不是按顺序加点,这里就要用到set(要是不嫌麻烦可以写treap),对每种颜色开一个set,权值是整棵树dfs序上的顺序。每次要新加一个点时,找到这个点对应颜色的set中的前驱后继,将这两个点的lca处权值+1(在加这个点之前,它的前驱后继两个点相邻,会使lca的权值-1,这里要加回来),再分别将这个点和它的前驱后继的lca处-1。这样就保证每一时刻一个颜色dfs序上相邻两个点的lca到根的路径上都去重了。
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int T;
int n,m;
int x,y;
int cnt;
int tot;
int num;
int ans;
int s[100010];
int t[100010];
int a[100010];
int d[100010];
int v[100010];
int to[100010];
int que[100010];
int ls[5000010];
int rs[5000010];
int next[100010];
int head[100010];
int sum[5000010];
int root[100010];
int f[100010][19];
set<int>q[100010];
set<int>::iterator it;
bool cmp(int x,int y)
{return d[x]<d[y];
}
void add(int x,int y)
{tot++;next[tot]=head[x];head[x]=tot;to[tot]=y;
}
int lca(int x,int y)
{if(d[x]<d[y]){swap(x,y);}int dep=d[x]-d[y];for(int i=0;i<=18;i++){if((dep&(1<<i))!=0){x=f[x][i];}}if(x==y){return x;}for(int i=18;i>=0;i--){if(f[x][i]!=f[y][i]){x=f[x][i];y=f[y][i];}}return f[x][0];
}
void dfs(int x)
{s[x]=++cnt;que[cnt]=x;for(int i=1;i<=18;i++){f[x][i]=f[f[x][i-1]][i-1];}for(int i=head[x];i;i=next[i]){d[to[i]]=d[x]+1;dfs(to[i]);}t[x]=cnt;
}
int updata(int pre,int l,int r,int k,int v)
{int rt=++cnt;if(l==r){sum[rt]=sum[pre]+v;return rt;}ls[rt]=ls[pre];rs[rt]=rs[pre];sum[rt]=sum[pre]+v;int mid=(l+r)>>1;if(k<=mid){ls[rt]=updata(ls[pre],l,mid,k,v);}else{rs[rt]=updata(rs[pre],mid+1,r,k,v);}return rt;
}
int query(int rt,int l,int r,int L,int R)
{if(!rt||(L<=l&&r<=R)){return sum[rt];}int mid=(l+r)>>1;if(L>mid){return query(rs[rt],mid+1,r,L,R);}else if(R<=mid){return query(ls[rt],l,mid,L,R);}else{return query(ls[rt],l,mid,L,R)+query(rs[rt],mid+1,r,L,R);}
}
int main()
{scanf("%d",&T);while(T--){tot=0;ans=0;cnt=0;num=0;memset(head,0,sizeof(head));memset(root,0,sizeof(root));memset(f,0,sizeof(f));scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",&v[i]);a[i]=i;q[i].clear();}for(int i=2;i<=n;i++){scanf("%d",&f[i][0]);add(f[i][0],i);}d[1]=1;dfs(1);sort(a+1,a+1+n,cmp);for(int i=1;i<=n;i++){x=y=0;it=q[v[a[i]]].lower_bound(s[a[i]]);root[d[a[i]]]=updata(root[d[a[i-1]]],1,n,s[a[i]],1);if(it!=q[v[a[i]]].end()){y=que[(*it)];root[d[a[i]]]=updata(root[d[a[i]]],1,n,s[lca(a[i],y)],-1);}if(it!=q[v[a[i]]].begin()){it--;x=que[(*it)];root[d[a[i]]]=updata(root[d[a[i]]],1,n,s[lca(a[i],x)],-1);}if(x&&y){root[d[a[i]]]=updata(root[d[a[i]]],1,n,s[lca(x,y)],1);}q[v[a[i]]].insert(s[a[i]]);}for(int i=1;i<=m;i++){scanf("%d%d",&x,&y);x^=ans;y^=ans;ans=query(root[min(d[x]+y,d[a[n]])],1,n,s[x],t[x]);printf("%d\n",ans);}}
}

转载于:https://www.cnblogs.com/Khada-Jhin/p/9449125.html

BZOJ4771七彩树——可持久化线段树+set+树链的并+LCA相关推荐

  1. BZOJ 3483 SGU505 Prefixes and suffixes(字典树+可持久化线段树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3483 [题目大意] 给出一些串,同时给出m对前缀后缀,询问有多少串满足给出的前缀后缀模 ...

  2. 主席树 - 可持久化线段树

    模板 P3834 [模板]可持久化线段树 2(主席树) 区间求第 \(k\) 大 模板代码 #include<bits/stdc++.h> using namespace std; #de ...

  3. Codeforces1422 F.Boring Queries(根号分治+线段树+可持久化线段树)

    题意: 解法: 如果问题可以离线,那么莫队可以直接冲过去,可惜离不得. 每个数最多只有一个>sqrt的质因子,sqrt(2e5)<90, 开90棵线段树分别维护前90个质因子的区间最大指数 ...

  4. 主席树 || 可持久化线段树 || LCA || BZOJ 2588: Spoj 10628. Count on a tree || Luogu P2633 Count on a tree...

    题面: Count on a tree 题解: 主席树维护每个节点到根节点的权值出现次数,大体和主席树典型做法差不多,对于询问(X,Y),答案要计算ans(X)+ans(Y)-ans(LCA(X,Y) ...

  5. bzoj 4771: 七彩树 树链的并+可持久化线段树

    题目大意: 给定一颗树,询问树中某个点x的子树中与其距离不超过d的所有点中本质不同的颜色数 强制在线 题解: 一下午终于把这道题叉掉了. 写了三个算法,前两个都是错的,后一个是%的网上大爷们的题解. ...

  6. SP10628 COT - Count on a tree (树剖+可持久化线段树)

    题意: 给定一个包含 N 个结点的树. 树节点从 1 到 N编号..每个节点有一个整数权值. 我们会要求您执行以下操作: u v k : 询问从节点 u 到 节点 v 的路径上的第k小的权值 输入 在 ...

  7. 解题报告:P3834 【模板】可持久化线段树 2(主席树)详解

    P3834 [模板]可持久化线段树 2(主席树) 题解 P3834 [[模板]可持久化线段树 2(主席树)] 1)静态求第k大数 可持久化线段树,不能用堆的方法存子结点了,所以用指针l表示左儿子r表示 ...

  8. 可持久化线段树——主席树

    前言: 最近心(po)血(yu)来(ya)潮(li)学习了一下主席树.(再不学就落伍了) 主席树,即可持久化线段树,支持维护和查询区间的第\(k\)大(小).区间不同种类个数等,基于线段树的思想之上 ...

  9. BZOJ.3218.a + b Problem(最小割ISAP 可持久化线段树优化建图)

    BZOJ UOJ 首先不考虑奇怪方格的限制,就是类似最大权闭合子图一样建图. 对于奇怪方格的影响,显然可以建一条边\((i\to x,p_i)\),然后由\(x\)向\(1\sim i-1\)中权值在 ...

  10. 【模板】可持久化线段树 1(主席树)

    题目背景 这是个非常经典的主席树入门题--静态区间第K小 数据已经过加强,请使用主席树.同时请注意常数优化 题目描述 如题,给定N个正整数构成的序列,将对于指定的闭区间查询其区间内的第K小值. 输入输 ...

最新文章

  1. 什么是pretext tasks?
  2. SSM整合框架实现ajax校验
  3. Cucumber入门之_argument
  4. FPGA图案--数字表示(代码+波形)
  5. 重磅!谷歌大脑提出EfficientNet平衡模型扩展三个维度,取得精度-效率的最大化!...
  6. Java线程 生产者--消费者模式总结(二)
  7. 计算机导论的计算题,计算机导论复习题(选择部分)汇总
  8. FortiClient cannot establish caused by TLS version
  9. 阻滞增长模型求解_阻滞增长模型logistic模型.ppt
  10. 树莓派人脸表情识别中期报告
  11. 不知道读什么?5种方法教你打造私房书单!
  12. 索骥馆-编程语言之《网络编程实用教程(第2版)》扫描版[PDF]
  13. 【开源项目】Imagine图片压缩工具
  14. 27岁女生零基础转行学软件测试,来的及吗,我陷入了迷茫......
  15. 教你写一个ftp协议(文件传输协议)
  16. 联想MIIX 510-12ISK 改Win7系统
  17. uefi装完系统后无法引导_戴尔DELL电脑重装win10开机启动不了无法引导解决方法...
  18. 某程序员工作一年感慨:看到代码就恶心,想转行销售,网友:你觉得人民币恶心吗?
  19. 计算机cpu组装图,组装电脑CPU安装和跳线接法(图文收藏)
  20. 专注HR 招聘SaaS市场,Moka还有多少上升空间?

热门文章

  1. 如何给拍好的短视频配音?最简单的方法推荐!
  2. ★如何解释特修斯之船问题?
  3. 相机内存卡照片删除怎么恢复
  4. 教你用Python如何完成一个查票系统实现123006自动抢票啦~
  5. python 下载mp4视频 实例
  6. Leetcode 905. Sort Array By Parity
  7. 学生请销假管理系统java_学生请假管理系统.doc
  8. typescript入门之:如何使用、不限定函数参数的个数传参、interface约束(对象、函数、数组、类)、定义可选参数
  9. 软件测试-软件测试总结
  10. 计算机术语中的channel,English 中关于道路方面用词之(4)—Channel, Tunnel