Ancient Distance

给定一颗根为111有nnn个节点的树,每次可以选定树上kkk节点当作特殊节点,

定义dis(u)dis(u)dis(u)为,从u−>1u->1u−>1遇上的第一个特殊点的距离,如果遇不上特殊点则dis(u)dis(u)dis(u)无穷大。

有nnn次询问,问,每次选k∈{1,2,3,…,n−1,n}k \in \{1, 2, 3, \dots, n - 1, n\}k∈{1,2,3,…,n−1,n}个特殊点时的答案,

有一个性质,最大答案为n−1n - 1n−1,且111号点是一定要选的,接下来考虑其他的点如何选取,

假设我们当前答案为xxx,我们需要选取多少个点,有一个贪心的想法,找到一个节点最深的节点,然后把他的第xxx代祖先设置为特殊点,

这样我们就保证了这一子树都满足答案小于等于xxx,按照这样依次操作,最后我们的答案都会小于xxx,

不难发现对于每个xxx,我们所需执行的操作最多不会超过⌈nx⌉\lceil \frac{n}{x} \rceil⌈xn​⌉,我们可以利用线段树来查询每次需要操作的点,这样保证了一次操作是log⁡n\log nlogn的,

由此我们发现整体复杂度是∑i=1n⌈ni⌉log⁡n=O(nlog⁡nlog⁡n)\sum\limits_{i = 1} ^{n} \lceil \frac{n}{i} \rceil \log n = O(n \log n \log n)i=1∑n​⌈in​⌉logn=O(nlognlogn)的。

#include <bits/stdc++.h>
#define mid (l + r >> 1)
#define lson rt << 1, l, mid
#define rson rt << 1 | 1, mid + 1, r
#define ls rt << 1
#define rs rt << 1 | 1using namespace std;const int N = 2e5 + 10;int maxn[N << 2], id[N << 2], cov[N << 2], ans[N], n;int l[N], r[N], rk[N], fa[N][21], dep[N], tot;vector<int> G[N];void dfs(int rt, int f) {l[rt] = ++tot, rk[tot] = rt, fa[rt][0] = f, dep[rt] = dep[f] + 1;for (int i = 1; i <= 20; i++) {fa[rt][i] = fa[fa[rt][i - 1]][i - 1];}for (int &to : G[rt]) {if (to == f) {continue;}dfs(to, rt);}r[rt] = tot;
}int k_fa(int rt, int k) {for (int i = 20; i >= 0; i--) {if (k >> i & 1) {rt = fa[rt][i];}}return rt;
}void push_up(int rt) {maxn[rt] = 0;if (!cov[ls] && maxn[ls] > maxn[rt]) {maxn[rt] = maxn[ls];id[rt] = id[ls];}if (!cov[rs] && maxn[rs] > maxn[rt]) {maxn[rt] = maxn[rs];id[rt] = id[rs];}
}void build(int rt, int l, int r) {cov[rt] = 0;if (l == r) {maxn[rt] = dep[rk[l]];id[rt] = rk[l];return ;}build(lson);build(rson);push_up(rt);
}void update(int rt, int l, int r, int L, int R, int v) {if (l >= L && r <= R) {cov[rt] = v;return ;}if (L <= mid) {update(lson, L, R, v);}if (R > mid) {update(rson, L, R, v);}push_up(rt);
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);while (scanf("%d", &n) != EOF) {tot = 0;for (int i = 1; i <= n; i++) {G[i].clear();}for (int i = 2, x; i <= n; i++) {scanf("%d", &x);G[x].push_back(i);G[i].push_back(x);}dep[0] = -1;dfs(1, 0);build(1, 1, n);for (int i = 1; i <= n; i++) {ans[i] = n;}vector<int> vt;for (int cur = n - 1; cur >= 0; cur--) {int num = 1;vt.clear();while (true) {if (maxn[1] <= cur) {break;}num++;int u = k_fa(id[1], cur);vt.push_back(u);update(1, 1, n, l[u], r[u], 1);}ans[num] = cur;for (auto rt : vt) {update(1, 1, n, l[rt], r[rt], 0);}}for (int i = 2; i <= n; i++) {ans[i] = min(ans[i], ans[i - 1]);}long long res = 0;for (int i = 1; i <= n; i++) {res += ans[i];}printf("%lld\n", res);}return 0;
}

Ancient Distance(妙啊!!!) [2020牛客暑期多校训练营(第四场)]相关推荐

  1. 2020牛客暑期多校训练营(第一场)

    文章目录 A B-Suffix Array B Infinite Tree C Domino D Quadratic Form E Counting Spanning Trees F Infinite ...

  2. 2020牛客暑期多校训练营(第二场)

    2020牛客暑期多校训练营(第二场) 最烦英语题 文章目录 A All with Pairs B Boundary C Cover the Tree D Duration E Exclusive OR ...

  3. E Groundhog Chasing Death(2020牛客暑期多校训练营(第九场))(思维+费马小定理+质因子分解)

    E Groundhog Chasing Death(2020牛客暑期多校训练营(第九场))(思维+费马小定理+质因子分解) 链接:https://ac.nowcoder.com/acm/contest ...

  4. 2020牛客暑期多校训练营(第一场)A B-Suffix Array(后缀数组,思维)

    链接:https://ac.nowcoder.com/acm/contest/5666/A 来源:牛客网 题目描述 The BBB-function B(t1t2-tk)=b1b2-bkB(t_1 t ...

  5. 2020牛客暑期多校训练营(第二场)Just Shuffle

    https://ac.nowcoder.com/acm/contest/5667/J 题目大意:给你一个置换A,使得置换P^k=A,让你求出置换P. 思路:我们根据置换A再置换z次,那么就等于置换p ...

  6. 2020牛客暑期多校训练营(第一场)j-Easy Integration(思维,分数取模,沃斯利积分)

    题目链接 题意: 给你一个积分公式,给你一个n,问积分公式的值取模后的结果. 思路: 积分公式(沃利斯积分)值的结论直接就是(n!)^2/(2n+1)!,求个阶乘,再用费马小定理给1/(2n+1)!取 ...

  7. 2020 牛客暑期多校训练营(第一场)F

    题目大意: 多次输入两个a,b字符串他们可以无限次的重复变成aaa,或者bbb 比较他们的大小,相同输出 =,a<b输出 <,a>b输出 >. 输入: aa b zzz zz ...

  8. 2020牛客暑期多校训练营(第二场)未完待续......

    F. Fake Maxpooling 题目: 题目大意: 输入n,m,k.矩阵的尺寸为nm,其中每一个元素为A[i][j] = lcm( i , j ).从中找出所有kk的子矩阵中元素最大的数之和. ...

  9. 2020牛客暑期多校训练营(第一场)J、Easy Integration (数学、分部积分)

    题目链接 题面: 题意: 求给定的定积分. 题解,化成 ∫ xn (1-x)n dx 然后用分部积分法即可得. 分部积分法:∫ udv = uv - ∫ vdu 最终为 n!/((n+1)*(n+2) ...

  10. 2020牛客暑期多校训练营(第二场)题解

    废话 蒟蒻不会积分,K不会做. 文章目录 废话 A. All with Pairs B. Boundary C. Cover the Tree D. Duration E. Exclusive OR ...

最新文章

  1. ROS中RVIS导入机器人模型,添加摄像头,雷达,Kinect
  2. 以太坊智能合约编程之带菜鸟入门教程
  3. 构建富互联网应用程序监控工作流和流程(4)
  4. tp5 cache缓存简单使用
  5. swift 选中长按项_Swift下使用UICollectionView 实现长按拖拽功能
  6. 华纳传媒和Discovery合并交易将提前完成 华纳CEO将在交易之前辞职
  7. 计算机应用基础离线考核,东师2016年秋季《计算机应用基础》期末考核离线作业...
  8. 中兴f477v2超级管理员_[求助] 联通光猫 ZXHN F477V2 桥接问题
  9. arduino 土壤温湿度传感器_arduino测量土壤湿度自动浇水提醒 - 全文
  10. winForm中 Invalidate(),Update(),Reflash(),
  11. WHENet: Real-time Fine-Grained Estimation for Wide Range Head Pose
  12. java透视图_Eclipse透视图
  13. 目标检测难题 | 小目标检测策略汇总
  14. 苹果电脑虚拟键盘怎么打开
  15. 关于SearchView的一些小细节
  16. 省钱兄校园跑腿源码(公众号+APP+小程序+Android+IOS)校园跑腿社区跑腿同城跑腿任务兼职小程序uniapp前端模版
  17. 软件的知识产权保护---著作权法及实施条例
  18. 糟糕!服务器被植入挖矿木马,CPU飙升200%
  19. 微信朋友圈投票活动的“刷票”案例分析。
  20. 物联网系统开发的11个步骤【看评论区里领取项目资料】

热门文章

  1. db2和mysql语句区别_db2和mysql语法的区别是什么
  2. 如何在Clion中使用C++调用Python代码
  3. java怎么实现同步到微博功能_新浪微博信息站外同步的完整实现
  4. 2000多一件的大牌T恤,真实成本有多少?
  5. 听说这是和女朋友住一起后的现象之一
  6. 中小学招生强化就近入学;首次全女性太空行走取消;苹果付费新闻APP奔溃;NASA火星上发现鹅卵石;这就是今天的大新闻...
  7. 《SAS编程与数据挖掘商业案例》学习笔记之十三
  8. promise 浏览器实现的源码_【大前端01-01】函数式编程与JS异步编程、手写Promise...
  9. android view存储为jpg,Android长按imageview把图片保存到本地的实例代码
  10. python随机数生成验证码_Python随机数random模块学习,并实现生成6位验证码