网站建设的知名公司装修流程先后顺序
web/
2025/9/29 8:00:02/
文章来源:
网站建设的知名公司,装修流程先后顺序,餐饮培训,免费搭建淘宝客网站Tree
让我们找满足一下五个条件的(x,y(x, y(x,y)点对有多少#xff1a; x≠yx \neq yxyxxx不是yyy的祖先yyy不是xxx的祖先dis(x,y)≤kdis(x, y)\leq kdis(x,y)≤kzzz是x,yx, yx,y的最近公共祖先#xff0c;valuexvaluey2valuezvalue_x value_y 2value_zvaluexvaluey…Tree
让我们找满足一下五个条件的(x,y(x, y(x,y)点对有多少
x≠yx \neq yxyxxx不是yyy的祖先yyy不是xxx的祖先dis(x,y)≤kdis(x, y)\leq kdis(x,y)≤kzzz是x,yx, yx,y的最近公共祖先valuexvaluey2valuezvalue_x value_y 2value_zvaluexvaluey2valuez。
读题目观察到每个节点的valuevaluevalue只有[0,105][0, 10 ^ 5][0,105]如果不是的话也可离散化处理一下吧所以我们可以建立10510 ^ 5105棵线段树每棵线段树里面记录的是点权为iii的节点的深度信息
所以我们只要做一次dsuontreedsu\ on\ treedsu on tree动态维护这颗线段树然后按照需要查询即可好像并不是特别难。
#include bits/stdc.husing namespace std;const int N 2e5 10;int head[N], to[N], nex[N], cnt 1;int value[N], n, m;int son[N], sz[N], dep[N], l[N], r[N], rk[N], tot;int root[N], ls[N 6], rs[N 6], sum[N 6], num;void add(int x, int y) {to[cnt] y;nex[cnt] head[x];head[x] cnt;
}void dfs(int rt, int fa) {dep[rt] dep[fa] 1, sz[rt] 1, l[rt] tot, rk[tot] rt;for (int i head[rt]; i; i nex[i]) {if (to[i] fa) {continue;}dfs(to[i], rt);sz[rt] sz[to[i]];if (!son[rt] || sz[son[rt]] sz[to[i]]) {son[rt] to[i];}}r[rt] tot;
}void push_up(int rt) {sum[rt] sum[ls[rt]] sum[rs[rt]];
}void update(int rt, int l, int r, int x, int value) {if (!rt) {rt num;}if (l r) {sum[rt] value;return ;}int mid l r 1;if (x mid) {update(ls[rt], l, mid, x, value);}else {update(rs[rt], mid 1, r, x, value);}push_up(rt);
}int query(int rt, int l, int r, int L, int R) {if (!rt) {return 0;}if (l L r R) {return sum[rt];}int mid l r 1, ans 0;if (L mid) {ans query(ls[rt], l, mid, L, R);}if (R mid) {ans query(rs[rt], mid 1, r, L, R);}return ans;
}long long ans;void dfs(int rt, int fa, bool keep) {for (int i head[rt]; i; i nex[i]) {if (to[i] fa || to[i] son[rt]) {continue;}dfs(to[i], rt, 0);}if (son[rt]) {dfs(son[rt], rt, 1);}int v 2 * value[rt], d dep[rt];for (int i head[rt]; i; i nex[i]) {if (to[i] fa || to[i] son[rt]) {continue;}for (int j l[to[i]]; j r[to[i]]; j) {int target_v v - value[rk[j]], last_d m - (dep[rk[j]] - d);//目标权值剩下的可延展的距离if (target_v 0 || last_d 0) {//如果目标权值小于0或者剩下的可延展距离没有了提前剪除不合法continue;}int l d 1, r d last_d;//深度的区间范围然后查询即可。ans query(root[target_v], 1, n, l, r);}for (int j l[to[i]]; j r[to[i]]; j) {update(root[value[rk[j]]], 1, n, dep[rk[j]], 1);}}update(root[value[rt]], 1, n, dep[rt], 1);if (!keep) {for (int i l[rt]; i r[rt]; i) {update(root[value[rk[i]]], 1, n, dep[rk[i]], -1);}}
}int main() {// freopen(in.txt, r, stdin);// freopen(out.txt, w, stdout);// ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);scanf(%d %d, n, m);for (int i 1; i n; i) {scanf(%d, value[i]);}for (int i 2; i n; i) {int x;scanf(%d, x);add(x, i);}dfs(1, 0);dfs(1, 0, 1);printf(%lld\n, ans * 2);return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/83787.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!