对于一个$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. Network Analyst Tools(Network Analyst 工具)

    Network Analyst 工具 1.分析 # Process: 创建 OD 成本矩阵图层 arcpy.MakeODCostMatrixLayer_na("", "O ...

  2. 2021.7.27--Benelux Algorithm Programming Contest 2020 补提

    I Jigsaw 题目内容: 链接:https://ac.nowcoder.com/acm/contest/18454/I 来源:牛客网 You have found an old jigsaw pu ...

  3. PAT (Basic Level) Practice (中文)1014 福尔摩斯的约会 (20分)

    1014 福尔摩斯的约会 (20分) 带侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk d&Hys ...

  4. clock时钟

    ①时钟的偏移(skew):时钟分支信号在到达寄存器的时钟端口过程中,都存在有线网等延时,由于延时,到达寄存器时钟端口的时钟信号存在有相位差,也就是不能保证每一个沿都对齐,这种差异称为时钟偏移(cloc ...

  5. ES2020新特性记录

    1.可选链操作符 // oldlet ret = obj && obj.first && obj.first.second// newlet ret = obj?.fi ...

  6. 反调试——11——检测TF标志寄存器

    反调试--11--检测TF标志寄存器 在intel的x86寄存器中有一种叫标志寄存器: 标志寄存器中的TF(Trap Flag)位,CPU在执行完一条指令后,如果检测到标志寄存器的TF位为1,则会产生 ...

  7. kiyv Button参数属性

    from kivy.uix.button import Button from kivy.uix.floatlayout import FloatLayout from kivy.app import ...

  8. [对对子队]会议记录4.18(Scrum Meeting9)

    今天已完成的工作 何瑞 ​ 工作内容:修复了一些关卡1的bug ​ 相关issue:搭建关卡1 ​ 相关签入:4.18签入1 4.18签入2 梁河览 ​ 工作内容:实现了音量控制,添加了BGM ​ 相 ...

  9. Linux线程互斥学习笔记--详细分析

    一.互斥锁 为啥要有互斥? 多个进程/线程执行的先后顺序不确定,何时切出CPU也不确定. 多个进程/线程访问变量的动作往往不是原子的. 1. 操作步骤 (1)创建锁 // 创建互斥锁mutex pth ...

  10. 华为HCIP-Eth-trunk原理知识点

    Eth-trunk(端口聚合.链路捆绑.链路聚合.以太通道) Eth-trunk技术出现的原因: • 随着网络中部署的业务量不断增长,对于全双工点对点链路,单条物理链路的带宽已不能满足正常的业务流量 ...