七彩树

Time Limit: 5 Sec Memory Limit: 256 MB

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个数为ci,分别表示每个节点的颜色。
第三行包含n-1个正整数,其中第i个数为fi+1,表示节点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

本来是个离线题的,就是说你按深度插入每个点。(当然要先树剖一下啦!)
单独维护每一个颜色,两个相邻的点就在lca的地方减一就好了。
但是他是个在线就的很毒。。。
我们以毒攻毒,用可持久化线段树。。。


#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 5;
struct lpl{int fa, dfn, top, son, size, deep;
}a[maxn];
struct ld{int id, dfn;inline bool operator < (const ld &A)const{return dfn < A.dfn;}
};
struct lpd{int sum, ls, rs;
}node[10000010];
int n, m, c[maxn];
int lastans, last, num, tot, opt, cnt, mxd, root = 1;
int d[maxn], rt[maxn * 5], ot[maxn], dp[maxn];
vector<int> point[maxn];
set<ld> s[maxn];
set<ld>::iterator iter, op, ed;
queue<int> q;namespace HLD{void dfs1(int t, int fa){a[t].size = 1; int tmp = 0; mxd = max(mxd, a[t].deep);for(int i = point[t].size() - 1; i >= 0; --i){int now = point[t][i]; if(now == fa) continue;a[now].deep = a[t].deep + 1; dfs1(now, t);a[t].size += a[now].size; if(tmp < a[now].size){tmp = a[now].size; a[t].son = now;}}}void dfs2(int t, int fa){a[t].dfn = ++num;if(a[t].son){a[a[t].son].top = a[t].top; dfs2(a[t].son, t);}for(int i = point[t].size() - 1; i >= 0; --i){int now = point[t][i]; if(now == fa || now == a[t].son) continue;a[now].top = now; dfs2(now, t);}}inline int LCA(int x1, int x2){if(a[a[x1].top].deep < a[a[x2].top].deep) swap(x1, x2);while(a[x1].top != a[x2].top){x1 = a[a[x1].top].fa; if(a[a[x1].top].deep < a[a[x2].top].deep) swap(x1, x2);}return (a[x1].deep > a[x2].deep) ? x2 : x1;}
}namespace SGT{inline void update(int t){node[t].sum = node[node[t].ls].sum + node[node[t].rs].sum;}void build(int &t, int l, int r){t = ++cnt; node[t].sum = 0; if(l == r) return;int mid = (l + r) >> 1;build(node[t].ls, l, mid); build(node[t].rs, mid + 1, r);}void Modify(int &t, int l, int r, int pos, int val){t = ++cnt; node[t] = node[last];if(l == r){node[t].sum += val; return;}int mid = (l + r) >> 1;if(pos <= mid){last = node[last].ls; Modify(node[t].ls, l, mid, pos, val);}else{last = node[last].rs; Modify(node[t].rs, mid + 1, r, pos, val);}update(t);}int Query(int t, int l, int r, int ql, int qr){if(l == ql && r == qr) return node[t].sum;int mid = (l + r) >> 1;if(qr <= mid) return Query(node[t].ls, l, mid, ql, qr);if(mid < ql) return Query(node[t].rs, mid + 1, r, ql, qr);return Query(node[t].ls, l, mid, ql, mid) + Query(node[t].rs, mid + 1, r, mid + 1, qr);}
}template<typename T>
inline void read(T &x){x = 0; static char c = getchar();while(!isdigit(c)) c = getchar();while(isdigit(c)){x = x * 10 + c - '0'; c = getchar();}
}template<typename T>
void write(T x){if(x / 10) write(x / 10);putchar(x % 10 + '0');
}inline void putit(){read(n); read(m); lastans = 0; mxd = 0;for(int i = 1; i <= n; ++i) {point[i].clear(); s[i].clear(); a[i].son = 0; read(c[i]);}for(int f, i = 1; i < n; ++i){read(f); a[i + 1].fa = f; point[f].push_back(i + 1);}
}inline void prepare(){a[root].deep = 1; num = 0; memset(rt, 0, sizeof(rt));HLD::dfs1(root, 0); a[1].top = 1; HLD::dfs2(root, 0);q.push(root); int now; tot = 0;while(!q.empty()){now = q.front(); q.pop(); d[++tot] = now; for(int i = point[now].size() - 1; i >= 0; --i) q.push(point[now][i]);}cnt = 0; SGT::build(rt[0], 1, n); opt = 0;bool qian, hou;for(int color, i = 1; i <= tot; ++i){color = c[d[i]];iter = s[color].insert((ld){d[i], a[d[i]].dfn}).first;qian = (iter != s[color].begin()); iter++; hou = (iter != s[color].end()); iter--;if(qian){iter--; op = iter; iter++;}if(hou){iter++; ed = iter; iter--;} if(qian && hou){last = rt[opt]; SGT::Modify(rt[++opt], 1, n, a[HLD::LCA(op -> id, ed -> id)].dfn, 1);}if(qian){last = rt[opt];SGT::Modify(rt[++opt], 1, n, a[HLD::LCA(op -> id, iter -> id)].dfn, -1);    }if(hou){last = rt[opt];SGT::Modify(rt[++opt], 1, n, a[HLD::LCA(iter -> id, ed -> id)].dfn, -1);    }last = rt[opt]; SGT::Modify(rt[++opt], 1, n, iter -> dfn, 1);ot[d[i]] = opt; dp[a[d[i]].deep] = d[i];}
}inline void workk(){int x, D;while(m--){read(x); read(D); x ^= lastans; D ^= lastans;D += a[x].deep; D = min(D, mxd);D = ot[dp[D]];lastans = SGT::Query(rt[D], 1, n, a[x].dfn, a[x].dfn + a[x].size - 1);write(lastans); putchar(10);}
}int main()
{int T; read(T); while(T--){putit();prepare();workk();        } return 0;
}

转载于:https://www.cnblogs.com/LLppdd/p/9780186.html

bzoj4771 七彩树相关推荐

  1. BZOJ4771 七彩树(dfs序+树上差分+主席树)

    考虑没有深度限制怎么做.显然的做法是直接转成dfs序上主席树,但如果拓展到二维变成矩形数颜色数肯定没法做到一个log. 另一种做法是利用树上差分.对于同种颜色的点,在每个点处+1,dfs序相邻点的lc ...

  2. 【BZOJ4771】七彩树 主席树+树链的并

    [BZOJ4771]七彩树 Description 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色,其中第i个节点的颜色为c[i].如果c[i]=c[j], ...

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

    BZOj #4771. 七彩树 description solution code description 给定一棵n个点的有根树,编号依次为1到n,其中1号点是根节点.每个节点都被染上了某一种颜色, ...

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

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

  5. 暑假训练-义乌(7.8-7.15)

    暑假训练 模拟赛 图表 数据 7.8(lxl) 7.9(lxl) 7.10(lxl) 7.11(lxl) 7.12(wls) 7.13(wls) 7.14(wls) 7.15(lfds) 训练 数据结 ...

  6. 计算机科学与技术(嵌入式)四年学习资料_文件目录树

    说明: 资料内容主要包括:计嵌专业2019级大学四年主要科目的各种电子资料,有电子实验报告.课程设计报告.课程设计项目.整理复习笔记.电子书.ppt.练习题.期末试卷.部分课程软件资源.科创项目,职业 ...

  7. 齐上云促管控 用友携手鲲鹏云服务绘就七彩小镇新画卷

    通过"用友+华为云鲲鹏云服务"的应用,七彩小镇已经成为中国企业上云及数智化转型的新标杆. 出品 | 常言道 作者 | 丁常彦 近年来,我国各地特色小镇建设热度一直居高不下,许多特色 ...

  8. [微小说]根际大战——守护圣树

    在土壤世界中,生活着无数的生灵,其中"根际圈"是这个世界的中心,在这里生活的"微生物"数量庞大.密集且种类繁多.它们依靠"圣树"而活,圣树与 ...

  9. 判断两个树是否相等和判断tree1是否包含tree2 python实现

    判断两个树是否相等 def equal(node_a, node_b):"""判断两个树是否相等:param node_a: :param node_b: :return ...

  10. 论文溯源树AMiner

    来自 DBLP.ArXiv.STM 等多家学术出版机构和平台的数据表明,在过去 20 年间,计算机科学.物理学.统计学等研究领域的出版物总量都有大幅增加.像 CVPR.AAAI 等有关人工智能等新兴领 ...

最新文章

  1. 从零开始一起学习SLAM | 三维空间刚体的旋转
  2. Odoo10 启动选项
  3. VTK:可视化之KochSnowflake
  4. 【Python CheckiO 题解】Sort Array by Element Frequency
  5. staf工作笔记-扩展stax官方实例的补坑说明
  6. Windows下NLB(分工作组与域环境)、服务器群集简单搭建
  7. Java并发包的理解
  8. 取色器——TakeColor绿色安全简单
  9. 高频电子线路张肃文第五版详解_高频电子线路第五版张肃文主编学习课件(上).ppt...
  10. 有哪些让人相见恨晚的记笔记方法?
  11. 简述计算机网络的五层协议体系结构,计算机网络五层协议体系结构分别是什么...
  12. Netgear WNR2000v3刷固件记
  13. py thon画一个实心五角星
  14. windows下制作iso文件,WinMount介绍
  15. 求分子分母最大公约数c语言,怎么求两个分数的最大公约数?
  16. 关闭Win10锁屏的防暴力破解功能
  17. Java工程师 操作系统(四) 面试题(Day35)
  18. 音视频开发(十九):运算符重载、继承、多态、模版
  19. 基于云开发的校园社区小程序 微信小程序开发实战 课设作业
  20. 金蝶BOS开发代码调用过程

热门文章

  1. TeaVM编译JAVA感想:看着简单,做起来真难
  2. 手枪射击不准,远超想象,5米就完全没准头
  3. 判刑不应区分未成年、精神病
  4. LINUX使用消息队列的代码
  5. 某项目中,doubango与NAT服务器的冲突
  6. 玉龙雪山还会存在多久
  7. eclipse Unable to build: the file dx.jar was not loaded from the SDK folder的解决办法
  8. java虚拟机内存_java虚拟机内存区域的划分以及作用详解
  9. java 表格布局_Java怎样把表格放在绝对定位的面板上
  10. VC++使用dump定位release程序崩溃问题