由数据范围可得出,不可能一次一次去进行回答询问,只能离线处理,然后\(O(1)\)解决。

考虑\(DP\)解决,先给出\(DP\)方程:

\(f_i=max(j+ \lceil \frac{s_{j+1}}{i} \rceil)\) (\(f_i\)表示为当前一次操作最多访问\(i\)个未访问的点的最小操作次数,\(s_i\)表示表示深度\(\geqslant i\)的节点个数)

式子右边的含义为前\(j\)次操作访问完前\(j\)层节点,后面每次都访问\(i\)个节点,可以发现这样的操作是最优的。若从贪心的角度来看,每次操作一定是尽量访问更多的点,若此时有额外的点可供选择,优先访问有儿子的节点,为以后操作保证最优性提供保障。

先感性地证明这个式子的正确性,也就是这个地方为什么取\(max\)。

① 若我们无法做到前\(j\)次操作访问完前\(j\)层节点,假设存在\(k\),可以做到前\(k\)次操作访问完前\(k\)层节点。可以发现第\(k\)层在第\(j\)层上面,那么在\(k\)层到\(j\)层的节点,我们无法做到通过\(j-k\)次操作全部访问完,可以得出式子:

\(\lceil \frac{s_{k+1}-s_{j+1}}{i} \rceil>j-k\)

变形得:

\(k+\lceil \frac{s_{k+1}}{i} \rceil>j+\lceil \frac{s_{j+1}}{i} \rceil\)

发现合法状态\(k\)比不合法状态\(j\)操作次数要多,所以通过取\(max\)可以去除\(j\)这种不合法情况。

② 若我们无法做到前\(j\)次操作访问完前\(j\)层节点时后面每次都访问\(i\)个节点,假设存在\(k\),可以做到前\(k\)次操作访问完前\(k\)层节点时后面每次都访问\(i\)个节点。可以发现第\(k\)层在第\(j\)层下面,那么可以做到每次都访问\(i\)个节点的层数会变小,所以合法状态\(k\)会比不合法状态\(j\)操作次数多。

由这两种情况,我们就可以得出,为了保证状态合法,转移时应取\(max\)。

设合法状态\(j,k\),假设状态\(j\)比状态\(k\)更优。

即\(j+ \lceil \frac{s_{j+1}}{i} \rceil>k+ \lceil \frac{s_{k+1}}{i} \rceil\)

\(\lceil \frac{s_{j+1}-s_{k+1}}{i} \rceil>k-j\)

\(\frac{s_{j+1}-s_{k+1}}{j-k}<-i\)

发现我们可以用斜率优化来优化复杂度,这里\(x\)为\(j\),\(y\)为\(s_{j+1}\),斜率为\(-i\)。

其他的一些实现细节就看代码吧。

\(code:\)

#include<bits/stdc++.h>
#define maxn 1000010
using namespace std;
typedef long long ll;
template<typename T> inline void read(T &x)
{
x=0;char c=getchar();bool flag=false;
while(!isdigit(c)){if(c=='-')flag=true;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
if(flag)x=-x;
}
int n,m,h,t;
ll deep_max,query_max;
ll f[maxn],s[maxn],q[maxn],query[maxn];
struct edge
{
int to,nxt;
}e[maxn];
int head[maxn],edge_cnt;
void add(int from,int to)
{
e[++edge_cnt]=(edge){to,head[from]};
head[from]=edge_cnt;
}
double x(int i)
{
return i;
}
double y(int i)
{
return s[i+1];
}
double slope(int j,int k)
{
return (y(j)-y(k))/(x(j)-x(k));
}
void dfs(int x,ll dep)
{
s[dep]++;
deep_max=max(deep_max,dep);
for(int i=head[x];i;i=e[i].nxt)
{
int y=e[i].to;
dfs(y,dep+1);
}
}
int main()
{
read(n),read(m);
for(int i=1;i<=m;++i)
read(query[i]),query_max=max(query_max,query[i]);
for(int i=2;i<=n;++i)
{
int fath;
read(fath),add(fath,i);
}
dfs(1,1);
for(int i=deep_max;i;--i) s[i]+=s[i+1];
for(int i=1;i<=deep_max;++i)
{
while(h<t&&slope(q[t],i)>slope(q[t],q[t-1])) t--;
q[++t]=i;
}
for(int i=1;i<=query_max;++i)
{
while(h<t&&slope(q[h],q[h+1])>-i) h++;
int j=q[h];
f[i]=j+(s[j+1]+i-1)/i;
}
for(int i=1;i<=m;++i) printf("%lld ",f[query[i]]);
return 0;
}

题解 洛谷 P3571 【[POI2014]SUP-Supercomputer】的更多相关文章

  1. 题解 洛谷P5018【对称二叉树】(noip2018T4)

    \(noip2018\) \(T4\)题解 其实呢,我是觉得这题比\(T3\)水到不知道哪里去了 毕竟我比较菜,不大会\(dp\) 好了开始讲正事 这题其实考察的其实就是选手对D(大)F(法)S(师) ...

  2. 题解 洛谷 P3396 【哈希冲突】(根号分治)

    根号分治 前言 本题是一道讲解根号分治思想的论文题(然鹅我并没有找到论文),正 如论文中所说,根号算法--不仅是分块,根号分治利用的思想和分块像 似却又不同,某一篇洛谷日报中说过,分块算法实质上是一种 ...

  3. 题解-洛谷P5410 【模板】扩展 KMP(Z 函数)

    题面 洛谷P5410 [模板]扩展 KMP(Z 函数) 给定两个字符串 \(a,b\),要求出两个数组:\(b\) 的 \(z\) 函数数组 \(z\).\(b\) 与 \(a\) 的每一个后缀的 L ...

  4. 题解-洛谷P4229 某位歌姬的故事

    题面 洛谷P4229 某位歌姬的故事 \(T\) 组测试数据.有 \(n\) 个音节,每个音节 \(h_i\in[1,A]\),还有 \(m\) 个限制 \((l_i,r_i,g_i)\) 表示 \( ...

  5. 题解-洛谷P4724 【模板】三维凸包

    洛谷P4724 [模板]三维凸包 给出空间中 \(n\) 个点 \(p_i\),求凸包表面积. 数据范围:\(1\le n\le 2000\). 这篇题解因为是世界上最逊的人写的,所以也会有求凸包体积 ...

  6. 题解-洛谷P4859 已经没有什么好害怕的了

    洛谷P4859 已经没有什么好害怕的了 给定 \(n\) 和 \(k\),\(n\) 个糖果能量 \(a_i\) 和 \(n\) 个药片能量 \(b_i\),每个 \(a_i\) 和 \(b_i\) ...

  7. 题解-洛谷P5217 贫穷

    洛谷P5217 贫穷 给定长度为 \(n\) 的初始文本 \(s\),有 \(m\) 个如下操作: \(\texttt{I x c}\),在第 \(x\) 个字母后面插入一个 \(c\). \(\te ...

  8. 题解 洛谷 P2010 【回文日期】

    By:Soroak 洛谷博客 知识点:模拟+暴力枚举 思路:题目中有提到闰年然后很多人就认为,闰年是需要判断的其实,含有2月29号的回文串,前四位是一个闰年那么我们就可以直接进行暴力枚举 一些小细节: ...

  9. 题解 洛谷P2158 【[SDOI2008]仪仗队】

    本文搬自本人洛谷博客 题目 本文进行了一定的更新 优化了 Markdown 中 Latex 语句的运用,加强了可读性 补充了"我们仍不曾知晓得 消失的 性质5 ",加强了推导的严谨 ...

随机推荐

  1. java 基本类型详解 及 常见问题

    鄙人不才,基础不好,趁着闲时简单学习一下,仅作学习分享,如有不正确地方还请各位看客不吝指出. 常用的基本类型有:byte(8).short(16).char(16,取值从0-65535[2^16-1] ...

  2. python3大特征之多态

    1.什么是多态 多态指的是一类事物有多种形态 例如: 动物有多种形态: 人,狗,猪 在程序中多态指的是,不同对象可以响应相同方法,并可以有自己不同的实现方式 2.为什么需要多态 案例分析: impor ...

  3. Idea激活JRebel

    选择license激活 UUID 生成地址: http://www.uuid.online 激活地址 http://jrebel-license.jiweichengzhu.com/ UUID

  4. 入门大数据---SparkSQL联结操作

    一. 数据准备 本文主要介绍 Spark SQL 的多表连接,需要预先准备测试数据.分别创建员工和部门的 Datafame,并注册为临时视图,代码如下: val spark = SparkSessio ...

  5. 入门大数据---Python基础

    前言 由于AI的发展,包括Python集成了很多计算库,所以淡入了人们的视野,成为一个极力追捧的语言. 首先概括下Python中文含义是蟒蛇,它是一个胶水语言和一个脚本语言,胶水的意思是能和多种语言集 ...

  6. 拿2k的前端开发都会做些什么?

    坐标珠海,前端程序媛一枚 实习时候做的是测试,2.5k+600餐补: 后来觉得对前端更有兴趣所以重新找工作,但是苦于没有经验,毕业第一年在一个传统行业的公司找到了一个前端岗位,薪酬4k,公司主要是接政 ...

  7. c# 操作Redis的五种基本类型总结

    在我们的项目中,通常会把数据存储到关系型数据库中,比如Oracle,SQL Server,Mysql等,但是关系型数据库对于并发的支持并不是很强大,这样就会造成系统的性能不佳,而且存储的数据多为结构化 ...

  8. 【PyMuPDF和pdf2image】Python将PDF转成图片

    前言: 在最近的测试中遇到一个与PDF相关的测试需求,其中有一个过程是将PDF转换成图片,然后对图片进行测试. 粗略的试了好几种方式,其中语言尝试了Python和Java,总体而言所找到的Python ...

  9. Tallest Cow,题解

    题目链接 题意: 问满足一系列形如ab可以相互看到的约束的所有奶牛的最大身高(最高的编号和高度已给出) 分析: 首先,这个可以互相看到指的是中间的人比两头的都矮,一条斜线看到的不行,那么其实我们就可以 ...

  10. 洛谷P5774,可爱的动态规划。

    如此可爱的动态规划见过么? 相信各位都非常喜欢动态规划,那我就写一道可爱的动态规划的题解吧. 题目:https://www.luogu.com.cn/problem/P5774 题意: 题意“挺明白” ...