Problem

辣鸡bzoj权限题,洛谷链接

题意概要:一棵 \(n\) 个点有根树。\(Q\) 次询问给出一个 \(K\),回答遍历完整棵树所需最少操作次数。每次操作可以选择访问不超过 \(K\) 个未访问的点,且这些点的父亲必须在之前被访问过。

Solution

一开始题意理解错了,以为同时段每个点都能扩展 \(k\) 次,然后就无耻地看了题解……但是有个证明网上都没写,这也正是写这篇博客的原因

大概意思是说,最优策略一定是先用 \(i\) 步取完前 \(i\) 层,然后选取剩下深度大于 \(i\) 的节点时每次都能取满。规范一下就是设 \(s[i]\) 表示深度大于 \(i\) 的节点个数,则答案为 \(\max\limits_{i=1}^n \{i+\lceil \frac {s[i]}k\rceil\}\)

然后就可以正常斜率优化了:维护点 \((i,s[i])\) 的上凸包,每次询问 \(i\) 则在凸包上找斜率为 \(-i\) 的直线所切的点

但是看题解的时候不清楚前边那个式子的正确性,为什么会存在一条分界线使得上面可以用 \(i\) 次选完 \(i\) 层,下面可以随意选

思考了一会才弄懂,对于一棵树,从底层选择一个最深的深度 \(d\),显然满足下部节点可以随意选择(目前没有下部节点),但是有可能上部节点不能在层数次内选完。若出现这种情况,则上部一定存在若干层节点特别多,导致无法消完,可以考虑将分界线挪到某一层的上一层,由于这层节点特别多,可以保证下部节点可以随意选择。所以存在分界线比深度 \(d\) 浅,将 \(d\) 减小继续判断直到无法挪动,则找到分界线

至于为什么 \(\max\limits_{i=1}^n \{i+\lceil \frac {s[i]}k\rceil\}\) 中取最大值即可,是因为如若没有选择到分界线,则算出的值一定比最终答案要小

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db; template <typename _tp> inline void read(_tp&x){
char c11=getchar();x=0;while(!isdigit(c11))c11=getchar();
while(isdigit(c11))x=x*10+c11-'0',c11=getchar();
} const int N = 1001000;
struct Edge{int v,nxt;} a[N+N];
int head[N], s[N], Ans[N], qy[N];
ll f[N];
int n,Q,tp,_,mxd; void dfs(int x,int ds){
++s[ds], mxd = max(mxd, ds);
for(int i=head[x];i;i=a[i].nxt)
dfs(a[i].v,ds+1);
} struct vec{
ll x,y;
inline void in(){read(x), read(y);}
friend inline vec operator - (const vec&A,const vec&B) {return (vec){A.x - B.x, A.y - B.y};}
friend inline db operator * (const vec&A,const vec&B) {return (db)A.x * B.y - (db)A.y * B.x;}
friend inline bool operator < (const vec&A,const vec&B) {return A.x!=B.x ? A.x<B.x : A.y>B.y;}
}p[N],stk[N]; int main(){
read(n), read(Q);
for(int i=1;i<=Q;++i) read(qy[i]);
for(int i=2,x;i<=n;++i) read(x), a[++_].v = i, a[_].nxt = head[x], head[x] = _;
dfs(1,0);
for(int i=n;~i;--i) s[i] += s[i+1];
for(int i=0;;++i){
vec nw = (vec) {i, s[i]};
while(tp > 1 and (stk[tp] - stk[tp-1]) * (nw - stk[tp]) >= 0) --tp;
stk[++tp] = nw;
if(!s[i]) break;
}
for(int i=1,t=1;i<=n;++i){
vec dir = (vec) {1, -i};
while(t < tp and (stk[t+1] - stk[t]) * dir < 0) ++t;
Ans[i] = (stk[t].y + (ll)i * stk[t].x + i-1) / i;
}
++mxd;
for(int i=1;i<=Q;++i){
if(Ans[qy[i]]) printf("%d ",Ans[qy[i]]);
else printf("%d ",mxd);
}
return 0;
}

题解-POI2014 Supercomputer的更多相关文章

  1. 【BZOJ】3835: [Poi2014]Supercomputer

    题意 \(n(1 \le 1000000)\)个点的有根树,\(1\)号点为根,\(q(1 \le 1000000)\)次询问,每次给一个\(k\),每一次可以选择\(k\)个未访问的点,且父亲是访问 ...

  2. BZOJ3835: [Poi2014]Supercomputer

    Description Byteasar has designed a supercomputer of novel architecture. It may comprise of many (id ...

  3. BZOJ3835[Poi2014]Supercomputer——斜率优化

    题目描述 Byteasar has designed a supercomputer of novel architecture. It may comprise of many (identical ...

  4. BZOJ3835 [Poi2014]Supercomputer 【斜率优化】

    题目链接 BZOJ3835 题解 对于\(k\),设\(s[i]\)为深度大于\(i\)的点数 \[ans = max\{i + \lceil \frac{s[i]}{k}\} \rceil\] 最优 ...

  5. 题解-POI2014 FAR-FarmCraft

    Problem bzoj权限题,洛谷上可提交 洛谷上的奇葩翻译不要看,很多条件缺漏 题意简述:给定一棵树,每条边权为1,给定所有点点权,每条边仅能走两次,求以一定顺序遍历整棵树后,使所有点中的到达时间 ...

  6. [POI2014]Supercomputer

    题目大意: 给定一个$n(n\le10^6)$个结点的有根树,从根结点开始染色.每次可以染和已染色结点相邻的任意$k$个结点.$q(q\le10^6)$组询问,每次给定$k$,问至少需要染几次? 思路 ...

  7. POI2014题解

    POI2014题解 [BZOJ3521][Poi2014]Salad Bar 把p当作\(1\),把j当作\(-1\),然后做一遍前缀和. 一个合法区间\([l,r]\)要满足条件就需要满足所有前缀和 ...

  8. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  9. BZOJ3524 & LOJ2432:[POI2014]代理商Couriers——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3524 https://loj.ac/problem/2432 给一个长度为n的序列a.1≤a[i] ...

随机推荐

  1. Aninteresting game HDU - 5975 (数学+lowbit)

    Let’s play a game.We add numbers 1,2...n in increasing order from 1 and put them into some sets. Whe ...

  2. OSI七层模型的每一层都有哪些协议

    TCP/IP: 数据链路层:ARP,RARP 网络层: IP,ICMP,IGMP 传输层:TCP ,UDP,UGP 应用层:Telnet,FTP,SMTP,SNMP. OSI: 物理层:EIA/TIA ...

  3. python3基本数据类型

    python3的基本数据类型: Number(数字).String(字符串).List(列表).Tuple(元组).Set(集合).Dictionary(字典) 不可变数据类型(3 个):Number ...

  4. eclipse mars2在高分辨率下(macpro)图标极小的问题

    Mac Pro装WIN10和Surface Pro同样有效 安装了Eclipse并且打开之后,发现图标显示极其细小,肉眼几乎无法看清了.这是由于Eclipse对高分屏没有作适配导致的. Windows ...

  5. 常见排序算法总结:插入排序,希尔排序,冒泡排序,快速排序,简单选择排序以及java实现

    今天来总结一下常用的内部排序算法.内部排序算法们需要掌握的知识点大概有:算法的原理,算法的编码实现,算法的时空复杂度的计算和记忆,何时出现最差时间复杂度,以及是否稳定,何时不稳定. 首先来总结下常用内 ...

  6. Golang 介绍与安装

    1.介绍与安装 Golang 是什么 Go 亦称为 Golang(按照 Rob Pike 说法,语言叫做 Go,Golang 只是官方网站的网址),是由谷歌开发的一个开源的编译型的静态语言. Gola ...

  7. 《java核心技术36讲》学习笔记-------杨晓峰(极客时间)

    非常荣幸作为晓峰哥的同事,之前就看过这篇文章,重写读一遍,再学习学习. 一.开篇词 初级.中级:java和计算机科学基础.开源框架的使用:高级.专家:java io/nio.并发.虚拟机.底层源码.分 ...

  8. Linux haproxy配置参数

    http-request option http-server-close option http-pretend-keepalive option httpclose option redispat ...

  9. 小白月赛13 B小A的回文串 (马拉车算法求最长回文子串)

    链接:https://ac.nowcoder.com/acm/contest/549/B来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言52428 ...

  10. 【CH2401】送礼物

    题目大意:NPC 子集和问题. 题解:先搜索一半的物品重量和,记录在一个数组中,并将该数组排序并去重.再搜索另一半物品,到达目标状态后,在前一半物品记录的重量中查找小于当前剩余重量的最大值,更新答案即 ...