对于一个$k$,可以二分枚举答案并判断,判断过程可以贪心找最深的点(线段树区间max)+倍增+线段树区间覆盖(清0)来实现,时间复杂度$o(klog_{2}n)$
考虑反过来,暴力枚举答案$x$并求出最少需要的点数量$f(x)=k$,那么$\forall \ f(x)\le i< f(x-1)$,都有$i$的答案为$x$
这样的复杂度看似仍然是$o(n^{2}log_{2}n)$,但发现一次贪心至少覆盖$x+1$个点或者已经是最后一次,也就是说最多说单次复杂度为$o(\lceil \frac{n}{x+1}\rceil log_{2}n)$,累加后通过调和级数保证复杂度为$o(nlog^{\ 2
}_{2}n)$
具体线段树的实现上可能比较难,可以再维护一个$tag[k]$表示,可能标记永久化+重新修改来实现会比较方便
另外常数较大,注意线段树常数

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 #define L (k<<1)
5 #define R (L+1)
6 #define mid (l+r>>1)
7 struct ji{
8 int nex,to;
9 }edge[N];
10 vector<int>v;
11 int E,n,x,head[N],dfn[N],sz[N],sh[N],tr[N<<2],tr2[N<<2],tag[N<<2],f[N][21];
12 void add(int x,int y){
13 edge[E].nex=head[x];
14 edge[E].to=y;
15 head[x]=E++;
16 }
17 void build(int k,int l,int r){
18 tag[k]=1;
19 if (l==r){
20 tr[k]=tr2[k]=sh[l];
21 return;
22 }
23 build(L,l,mid);
24 build(R,mid+1,r);
25 tr[k]=tr2[k]=max(tr[L],tr[R]);
26 }
27 void update(int k,int l,int r,int x,int y,int z){
28 if ((l>y)||(x>r))return;
29 if ((x<=l)&&(r<=y)){
30 tag[k]=z;
31 tr[k]=tr2[k]*z;
32 return;
33 }
34 update(L,l,mid,x,y,z);
35 update(R,mid+1,r,x,y,z);
36 tr[k]=max(tr[L],tr[R])*tag[k];
37 }
38 int query(int k,int l,int r){
39 if (l==r)return l;
40 if (tr[k]==tr[L])return query(L,l,mid);
41 return query(R,mid+1,r);
42 }
43 void dfs(int k,int fa,int s){
44 sz[k]=1;
45 sh[k]=s;
46 dfn[k]=++x;
47 f[k][0]=fa;
48 for(int i=1;i<=20;i++)f[k][i]=f[f[k][i-1]][i-1];
49 for(int i=head[k];i!=-1;i=edge[i].nex){
50 dfs(edge[i].to,k,s+1);
51 sz[k]+=sz[edge[i].to];
52 }
53 }
54 int find(int k,int x){
55 for(int i=0;i<=20;i++)
56 if (x&(1<<i))k=f[k][i];
57 return k;
58 }
59 int main(){
60 while (scanf("%d",&n)!=EOF){
61 E=0;
62 for(int i=1;i<=n;i++)head[i]=-1;
63 for(int i=2;i<=n;i++){
64 scanf("%d",&x);
65 add(x,i);
66 }
67 x=0;
68 dfs(1,1,1);
69 build(1,1,n);
70 int ans=-1;
71 for(int i=1;i<=n;i++){
72 v.clear();
73 while (1){
74 x=find(query(1,1,n),i);
75 if (x==1)break;
76 v.push_back(x);
77 update(1,1,n,dfn[x],dfn[x]+sz[x]-1,0);
78 }
79 for(int j=0;j<v.size();j++)update(1,1,n,dfn[v[j]],dfn[v[j]]+sz[v[j]]-1,1);
80 ans+=v.size()+1;
81 }
82 printf("%d\n",ans);
83 }
84 }

[nowcoder5669A]Ancient Distance的更多相关文章

  1. [LeetCode] Total Hamming Distance 全部汉明距离

    The Hamming distance between two integers is the number of positions at which the corresponding bits ...

  2. [LeetCode] Hamming Distance 汉明距离

    The Hamming distance between two integers is the number of positions at which the corresponding bits ...

  3. [LeetCode] Rearrange String k Distance Apart 按距离为k隔离重排字符串

    Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...

  4. [LeetCode] Shortest Distance from All Buildings 建筑物的最短距离

    You want to build a house on an empty land which reaches all buildings in the shortest amount of dis ...

  5. [LeetCode] Shortest Word Distance III 最短单词距离之三

    This is a follow up of Shortest Word Distance. The only difference is now word1 could be the same as ...

  6. [LeetCode] Shortest Word Distance II 最短单词距离之二

    This is a follow up of Shortest Word Distance. The only difference is now you are given the list of ...

  7. [LeetCode] Shortest Word Distance 最短单词距离

    Given a list of words and two words word1 and word2, return the shortest distance between these two ...

  8. [LeetCode] One Edit Distance 一个编辑距离

    Given two strings S and T, determine if they are both one edit distance apart. 这道题是之前那道Edit Distance ...

  9. [LeetCode] Edit Distance 编辑距离

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

随机推荐

  1. Spatial Analyst 工具-数学分析

    数学分析 # Process: Abs arcpy.gp.Abs_sa("", 输出栅格) # Process: Exp arcpy.gp.Exp_sa("", ...

  2. Java初步学习——2021.10.10每日总结,第五周周日

    (1)今天做了什么: (2)明天准备做什么? (3)遇到的问题,如何解决? 今天继续学习菜鸟教程java字符串实例 5.字符串反转--reverse方法 public class Main { pub ...

  3. SpringMVC 数据响应

    页面跳转 返回字符串形式 直接返回字符串:此种方式会将返回的字符串与视图解析器的前后缀拼接后跳转. @RequestMapping("/quick") public String ...

  4. 分布式/微服务必配APM系统,SkyWalking让你不迷路

    前言 如今分布式.微服务盛行,面对拆分服务比较多的系统,如果线上出现异常,需要快速定位到异常服务节点,假如还用传统的方式排查肯定效率是极低的,因为服务之间的各种通信会让定位更加繁琐:所以就急需一个分布 ...

  5. JavaScript04

    分离绑定事件 使用分离方式绑定元素事件可以使用页面元素与JavaScript代码完全分离,有利于代码分工和维护,是目前开发主流,分为两步: 1.获取需要绑定事件的元素 语法:根据id属性值取元素节点 ...

  6. 【UE4 C++】关卡切换、流关卡加载卸载

    切换关卡 基于 UGameplayStatics:: OenLevel UGameplayStatics::OpenLevel(GetWorld(), TEXT("NewMap") ...

  7. 【c++ Prime 学习笔记】第11章 关联容器

    关联容器的元素按照关键字来保存和访问,而顺序容器的元素是按照在容器中的位置来保存和访问 关联容器支持高效的关键字查找和访问 2种关联容器: map中的元素是关键字-值对(key-value对),关键字 ...

  8. linux系统上国际化失败

    文章目录 一.需求: 二.出现的问题 三.代码结构 1.配置文件中的配置 2.java代码中的使用 四.解决方案 一.需求: 最近项目中有这么一个需求,当用户当前的语言环境是 中文时,导出的 exce ...

  9. 零基础如何更好的学习Linux

    本节旨在介绍对于初学者如何学习 Linux 的建议.如果你已经确定对 Linux 产生了兴趣,那么接下来我们介绍一下学习 Linux 的方法. 如何去学习 学习大多类似庖丁解牛,对事物的认识一般都是由 ...

  10. 局域网(以太网与IEEE 802.3、IEEE 802.11、)

    文章转自:https://blog.csdn.net/weixin_43914604/article/details/105016637 学习课程:<2019王道考研计算机网络> 学习目的 ...