首页 > 其他分享 >P3571 [POI2014]SUP-Supercomputer 题解

P3571 [POI2014]SUP-Supercomputer 题解

时间:2023-02-24 13:59:31浏览次数:40  
标签:dep 题解 sum Supercomputer 均摊 int ans 深度 P3571

首先有一个结论,树中存在一个深度 \(dep\),使得深度小于等于 \(dep\) 的点只需 \(dep\) 次覆盖完,而大于 \(dep\) 的除最后一次外其他每次都可以填充 \(k\) 次。

证明:在 \(dep\) 上面的所有点如果不能连续填充 \(k\) 次,说明均摊下来每一层的点数肯定小于 \(k\),这样的话一定存在上面的只用取 \(dep\) 次的深度,那下面层数均摊大于 \(k\),所以每次能填满 \(k\) 次,所以就是在找一个层数均摊为 \(k\) 的分界点,那么这种层数一定存在。

层数均摊什么意思呢,就是如果一层的节点大于了 \(k\),我们就将多余的节点放到下一个一层不足 \(k\) 个的深度上去。

现在我们就是对于每一个 \(k\),找到这个深度即可。

假设 \(i\) 是这个分界点,那么对于其他的深度,答案一定是小于等于它的。

证明上述:若深度小于 \(i\),那么会多包含能填满 \(k\) 的深度,那么就会多选节点,如果深度大于 \(i\),那么层度均摊大于 \(k\) 的一层会被一次选完,明显这两种情况都更优。

那么我们就可以列出式子,设 \(sum_i\) 为在 \(i\) 层及以下的节点个数。

那么 \(i+\left\lceil\frac{sum_i}{k}\right\rceil\ge j+\left\lceil\frac{sum_j}{k}\right\rceil\)。

相当于我们要求一个 \(i\) 使得 \(i+\left\lceil\frac{sum_i}{k}\right\rceil\) 最大。

设答案为 \(ans\),那么:

\[\begin{aligned} \\ans&=i+\left\lceil\frac{sum_i}{k}\right\rceil \\k\times ans&=k\times i+sum_i \\-sum_i&=k\times i-k\times ans \end{aligned}\]

上面明显是个斜率式子,考虑维护凸包,由于要求最大值,而截距越大答案越小,所以考虑维护下凸包。

那么每一个点即为 \((i,sum_{i+1})\)。

维护凸包后,对于询问,按 \(k\) 递减排序,用单调队列去找凸包上的点即可。

#include<iostream>
#include<cstdio>
#include<algorithm>
#define pii pair<int,int>
using namespace std;
const int N=1e6+5;
int n,m,q[N],dep[N],sum[N],maxn,ans[N];
pii a[N];
int cmp(pii x,pii y)
{
	return x.second<y.second;
}
inline double slope(int x,int y)
{
	if(x==y)return 1e9;
	return (-sum[x+1]+sum[y+1])*1.0/1.0/(x-y);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++)scanf("%d",&a[i].second),a[i].first=i;
	sort(a+1,a+1+m,cmp);
	sum[1]=dep[1]=1;
	for(int i=2;i<=n;i++)
	{
		int x;
		scanf("%d",&x);
		dep[i]=dep[x]+1;
		maxn=max(maxn,dep[i]);
		sum[dep[i]]++;
	}
	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&&slope(q[r],q[r-1])>=slope(i,q[r]))r--;
		q[++r]=i;
	}
	for(int i=1;i<=m;i++)
	{
		while(l<r&&slope(q[l],q[l+1])<a[i].second)l++;
		ans[a[i].first]=q[l]+(sum[q[l]+1]+a[i].second-1)/a[i].second;
	}
	for(int i=1;i<=m;i++)printf("%d ",ans[i]);
	return 0;
}
/*
20 3
2 3 1
1 1 1 3 4 3 2 8 6 9 10 12 12 13 14 11 11 11 11
*/

标签:dep,题解,sum,Supercomputer,均摊,int,ans,深度,P3571
From: https://www.cnblogs.com/gmtfff/p/p3571.html

相关文章

  • P4768 [NOI2018] 归程 题解
    这是一个悲伤的题目,自这道题后,\(\text{Noi}\)再无\(\text{SPFA}\)。首先讲一下重构树是啥。重构树是基于\(\text{kurskal生成树}\)算法的一棵树,对于每一次合并一条......
  • P3247 [HNOI2016]最小公倍数 题解
    题意简述:给定一个无向图,边权带两个值\((a,b)\),给定\(q\)次询问,每次询问给定两个点,求两个点直接是否有\(\max(a)=x\)且\(\max(b)=y\)的简单或非简单路径。解:如果......
  • P2489 [SDOI2011]迷宫探险 题解
    题意简述:一个\(n\timesm\)的带墙体单入口多出口迷宫中有\(k\)个陷阱,陷阱分为有害或无害,有害会使人掉血,给出所有垃圾的有害与无害的所有排列组成的概率,给定人的血量,求......
  • P4416 [COCI2017-2018#1] Plahte 题解
    题意简述:给定\(n\)个互不相交,可以重叠的矩阵,对某些点染色,这个点上的所有矩阵会被染上这个颜色,求最后每个矩阵会有多少种颜色。解:我们可以先把矩阵拆成上下两条水平线......
  • CF1034A Enlarge GCD 题解
    题意简述:删去最少的数使所有的数的\(\text{gcd}\)增加。解:先对每个数除以所有数的\(\text{gcd}\),然后剩下的需要找到所有数的质因子,找到一个最多的序列中数拥有的质......
  • CF436E Cardboard Box 题解
    一道经典的反悔贪心题。考虑每次选择使总星数加一,那么总共有四种情况。一、对于一关没有星,选一颗星,代价为\(a_i\)。二、对于一关有一颗星,再选一颗星,代价为\(b_i-a_i\)......
  • CF204E Little Elephant and Strings 题解
    由于是多个串,还与每个子串的信息有关,很容易想到用SA或广义SAM。这里选择用SA。首先先把字符串转化为数组,连接起来,中间用一些不会出现的数。处理出后缀数组与\(height......
  • P5842 [SCOI2012]Blinker 的仰慕者 题解
    题意简述:求\([l,r]\)内各个数位积为\(k\)的数的和。解:在看题解前,请先确认自己是否精通了数位dp模板题,否则会很难理解。对于朴素的数位dp,我们可以记录\(f_{i,j......
  • P5416 [CTSC2016]时空旅行 题解
    首先题中的\(y,z\)好像没啥用……首先对于每一次询问,要求\(\min((x_0-x_i)^2+c_i)\)设\((x_0-x_i)^2+c_i=ans\)。那么\(x_0^2+x_i^2-2x_0x_i+c_i=ans\)所以\(x_0......
  • P7862 [COCI2015-2016#2] DRŽAVA 题解
    适当进行骗分是真的有用。\(40pts\):对于每两个点建立一条边,然后在贪心每次求最小边,在期间进行01背包即可,01背包用于处理模数。设\(dp_{i,j}\)代表以\(i\)为编号的一......