P3571 [POI2014] SUP-Supercomputer 题解

news/2024/10/19 15:49:31

P3571「POI2014」SUP-Supercomputer 题解

一道 “较” 水的黑题 (可一开始苦思冥想还是不会)

本蒟蒻的第一篇黑题题解,求赞。

题意简化

给定一棵 $n$ 个节点、根节点为 $1$ 的有根树。$q$ 次询问中每次给定一个 $k$,输出需要最少用几次操作次数 删除 完整棵树。每次操作可以选择 删除 不超过 $k$ 个未访问的点,且这些点 没有父亲(血腥的味道)

前置知识

有一个 小小 的结论:存在一个 $i$,满足可以用 $i$ 次操作删掉所有深度小于等于 $i$ 的点,剩下的操作每次都删掉 $k$ 个点。

形式化地,设 $f_k$ 为 $k$ 对应的答案,$s_i$ 是深度大于 $i$ 的点数,有:
$$
f_k=\max_i \lceil\frac{s_i}{k}\rceil+i
$$

  • Why?

显然 ,要证明 $f_k=\max_i \lceil\frac{s_i}{k}\rceil+i$,转换为不等式,可分别证明 $f_k\ge\max_i \lceil\frac{s_i}{k}\rceil+i$ 和 $f_k\le\max_i \lceil\frac{s_i}{k}\rceil+i$:

  1. 证明 $f_k\ge\max_i \lceil\frac{s_i}{k}\rceil+i$ :
    可以注意到一个性质,要删除至少一个深度为 $i$ 的点,至少需要 $i$ 次操作。那么有 $f_k\ge \max_i \lceil\frac{s_i}{k}\rceil+i$。

  2. 证明 $f_k\le\max_i \lceil\frac{s_i}{k}\rceil+i$ :
    设 $f_{k,i}=i+\lceil\frac{s_i}{k}\rceil$,$f_{k,i}$ 在 $i=a$ 时取最大值。我们假设 $b$ 步可以删除完前 $b$ 层的节点,且这是满足条件的最大的 $b$,即证 $a=b$。

    • 先证 $a\ge b$:对于 $c<b$,若 $f_{k,c}>f_{k,b}$,则深度范围在 $(c,b]$ 之间的点数大于 $k(b−c)$,删掉一个第 $c$ 层的点至少要 $c$ 步,删掉 $c+1$ 到 $b$ 层的所有点要大于 $(b−c)$ 步,那么前 $b$ 层肯定 $b$ 次删不完,矛盾。因此 $a\ge b$。

    • 再证 $a\le b$:

      1. 第 $b+1$ 层一定有超过 $k$ 个节点,$f_{k,b+1}\le f_{k,b}$。
      2. 若第 $b+1$,$b+2$ 层点数之和不超过 $2k$,那么第 $b+2$ 层的点数一定不足 $b+1$ 层的,我们可以 $b+2$ 次删除完前 $b+2$ 层,矛盾,因此第 $b+1$,$b+2$ 层点数之和大于 $2k$,$f_{k,b+2}\le f_{k,b}$。

      以此类推 $a\le b$。
      所以 $a=b$,即 $f_k\le\max_i \lceil\frac{s_i}{k}\rceil+i$。

根据上面对 $a\le b$ 的证明,可以归纳证明第 $b+1$ 到第 $b+t$ 层的点数之和大于 $kt$,于是我们只需要一层一层删掉,并优先删除有儿子的结点就一定可行。这样 $f_k=\max_i \lceil\frac{s_i}{k}\rceil+i$,证毕。

题目解法

嘿嘿,大脑有没有烧了呢?有了以上结论,这道题就可以 切了。

对 $f_k=\max_i \lceil\frac{s_i}{k}\rceil+i$ 进行变形:
$$
f_k=\max_i \lceil\frac{s_i}{k}\rceil+i=f_k= \max_i \lceil\frac{s_i+ki}{k}\rceil
$$
所以,只需求 $g_k=\max s_i+ki$ 。

则:$s_i=-ki+g_k$($y=kx+b$)。

斜率优化即可,横坐标和斜率都单调,复杂度 $\mathcal{O}(n)$。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,q[N],dep[N];
int sum[N],maxn,ans[N];
struct __{int x,y;bool operator<(const __ x)const{return y<x.y;}
}a[N];
double slp(int x,int y){if(x==y)return 1e9;return (sum[y+1]-sum[x+1])*1.0/(x-y);
}
signed main(){ios::sync_with_stdio(0);cin.tie(0); cout.tie(0);cin>>n>>m;sum[1]=dep[1]=1;for(int i=1;i<=m;i++)cin>>a[i].y,a[i].x=i;stable_sort(a+1,a+m+1);for(int i=2,x;i<=n;i++){cin>>x; dep[i] = dep[x]+1;maxn = max(maxn , dep[i]);sum[dep[i]]=sum[dep[i]]+1;}for(int i=maxn;i>0;i--)sum[i]+=sum[i+1];int l=1,r=1;for(int i=1;i<=maxn;i++){while(l<r&&slp(i,q[r])<=slp(q[r],q[r-1]))r--;q[++r]=i;}for(int i=1;i<=m;i++){while(l<r&&a[i].y>slp(q[l],q[l+1]))l++;int k=q[l],Y=a[i].y,X=a[i].x;ans[X] = k+(sum[k+1]+Y-1)/Y ;}for(int i=1;i<=m;i++)cout<<ans[i]<<" ";return 0;
}

完 结 撒 花 ! ! !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/73472.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

Spring IoC

一、Spring IoC的理解IoC(Inversion of Control:控制反转) 是一种设计思想,而不是一个具体的技术实现。IoC 的思想就是将原本在程序中手动创建对象的控制权,交由 Spring 框架来管理。不过, IoC 并非 Spring 特有,在其他语言中也有应用。 控制反转?控制:指的是对象创建(…

修改VS的代码高亮颜色

点击工具->选项选择“字体和颜色”找到“用户成员-xx”、“用户类型-xx”,点击即可修改前景色、背景色

ArkUI-Image详解

ArkUI-Image详解 文章摘要: 给Image组件设置属性可以使图片显示更灵活,达到一些自定义的效果。以下是几个常用属性的使用示例。这时可以使用interpolation属性对图片进行插值,使图片显示得更清晰。Image组件引入本地图片路径,即可显示图片(根目录为ets文件夹)。通过rende…

强化学习算法笔记之【DDPG算法】

强化学习笔记第2篇,讲解DDPG算法。 感兴趣可以参考或者复刻。强化学习笔记之【DDPG算法】 目录强化学习笔记之【DDPG算法】前言:原论文伪代码DDPG 中的四个网络代码核心更新公式前言: 本文为强化学习笔记第二篇,第一篇讲的是Q-learning和DQN 就是因为DDPG引入了Actor-Crit…

python输出hello world

输出print("hello world")

2161: 【例9.3】小写字母转大写字母 【超出字符数据范围】

include <bits/stdc++.h> using namespace std; int main( ) { char a; cin >> a; cout << char(a-32); return 0; } // 反思1: cin >> a; 忘记写了 反思2: +是转为小写字母-是转为大写字母 【做错】

航飞参数计算

作者:太一吾鱼水 宣言:在此记录自己学习过程中的心得体会,同时积累经验,不断提高自己! 声明:博客写的比较乱,主要是自己看的。如果能对别人有帮助当然更好,不喜勿喷! 文章未经说明均属原创,学习笔记可能有大段的引用,一般会注明参考文献。 欢迎大家…

第4课 SVN

1、svn的定义: svn是一个开放源代码的版本控制系统,通过采用分支管理系统的高效管理,简而言之就是用于多个人共同开发同一个项目,实现共享资源,实现最终集中式管理。 2.snv的作用: 在项目中对需求规格说明书,测试用例,代码,以及项目项目的文件进项管理和分享。 3、svn…