P3571 [POI2014] SUP-Supercomputer 题解

1|0P3571「POI2014」SUP-Supercomputer 题解


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

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

题意简化

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

前置知识

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

形式化地,设 fkk 对应的答案,si 是深度大于 i 的点数,有:

fk=maxisik+i

  • Why?

显然 ,要证明 fk=maxisik+i,转换为不等式,可分别证明 fkmaxisik+ifkmaxisik+i

  1. 证明 fkmaxisik+i
    可以注意到一个性质,要删除至少一个深度为 i 的点,至少需要 i 次操作。那么有 fkmaxisik+i

  2. 证明 fkmaxisik+i
    fk,i=i+sikfk,ii=a 时取最大值。我们假设 b 步可以删除完前 b 层的节点,且这是满足条件的最大的 b,即证 a=b

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

    • 再证 ab

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

      以此类推 ab
      所以 a=b,即 fkmaxisik+i

根据上面对 ab 的证明,可以归纳证明第 b+1 到第 b+t 层的点数之和大于 kt,于是我们只需要一层一层删掉,并优先删除有儿子的结点就一定可行。这样 fk=maxisik+i,证毕。

题目解法

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

fk=maxisik+i 进行变形:

fk=maxisik+i=fk=maxisi+kik

所以,只需求 gk=maxsi+ki

则:si=ki+gky=kx+b)。

斜率优化即可,横坐标和斜率都单调,复杂度 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; }

完 结 撒 花 ! ! !


__EOF__

本文作者_NightFire666_
本文链接https://www.cnblogs.com/NightFire666-blog/p/18475969/P3571-Solution.html
关于博主:_NightFire666_
版权声明:转载请注明来源哟~ QAQ
声援博主:UP UP UP !!!
posted @   夜·煞  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架
点击右上角即可分享
微信分享提示