洛谷3571 POI2014 SUP-Supercomputer (斜率优化)
一道神仙好题。
首先看到有多组\(k\),第一反应就是离线。
考虑贪心。
我们每次一定是尽量选择有儿子的节点。以便于我们下一次扩展。
但是对于一个\(k\),每次贪心的复杂度是\(O(n)\)
总复杂度是\(O(nq)\),肯定过不了。
qwq
那我们只能来考虑一个快速求一个\(k\)的答案。
感觉题解的柿子好神仙啊。
这里定义\(f[i]\)表示\(k=i\)的时候的最小次数。
\(sum[i]\)表示深度大于等于\(i\)的点有多少个。
则$$f[i]=max(j+\lceil \frac{sum[j+1]}{i} \rceil)$$
含义是用了\(i\)次把全\(i\)层都取掉,然后剩下的每次都能取满。
qwq现在来解释一下为什么是这个柿子。
首先,比较容易证明答案一定在所有的\((j+\lceil \frac{sum[j+1]}{i} \rceil\)中,因为这已经是最优情况了(前i次最多取i层,而后面也是每次取满,所以一定是最优的情况,不存在更优秀的情况。)
那么为什么是要取\(max\)呢。
是为了避免不合法的情况。
这里不合法的情况有两种情况,首先是前\(i\)次取不满\(前i层\)。那么如果存在这个情况,一定存在\(j\)使得,前\(j\)层能够\(j\)次取满,但是\(j到i\)不能用\(j-i\)取满,则存在等式
\]
\]
那么取\(max\),这种不合法的情况就能排除。
另一种不合法的情况就是,后面的次数并不能每次都取满。
如果上面的情况合法,那么一定存在$$\lceil \frac{sum[i+1]-sum[i+x+1]}{k} \rceil + i+x+1 > \lceil \frac{sum[i+1]}{k} \rceil + i$$
因为存在一层满足不能够一次用满k,且没有多余的东西让他选,那这时候等式左边的\(i+x+1\)等于该层的时候,一定比原本的柿子更大。
至于为什么不存在一个小于\(max\)并且合法的情况,是因为一层最少需要一次。而如果存在\(min\),说明要满足用小于\(j\)次,选完\(j\)层,而这个东西是不可能的。
qwq
那么证明到这里,大概能说明上述的柿子的是对的了。
也就是
\]
那接下来应该怎么优化呢。
我们将上述柿子进行变形
\]
那么如果存在一个\(j>k\)且\(j比k\)优秀的话,应该满足
\]
经过化简,$$\frac{sum[j+1]-sum[k+1]}{j-k}>-i$$
直接上斜率优化就好
\(sum\)数组可以直接通过前缀和求出来
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define mk make_pair
#define ll long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return x*f;
}
const int maxn = 1e6+1e2;
int sum[maxn];
int n,m;
int point[maxn],nxt[maxn],to[maxn];
int cnt;
int deep[maxn];
int dp[maxn];
int a[maxn];
void addedge(int x,int y)
{
nxt[++cnt]=point[x];
to[cnt]=y;
point[x]=cnt;
}
struct Point{
ll x,y,num;
};
Point q[maxn];
ll chacheng(Point x,Point y)
{
return x.x*y.y-x.y*y.x;
}
bool Count(Point i,Point j,Point k)
{
Point x,y;
x.x=k.x-i.x;
x.y=k.y-i.y;
y.x=k.x-j.x;
y.y=k.y-j.y;
if (chacheng(x,y)>=0) return true;
return false;
}
int head=1,tail=0;
void push(Point x)
{
while(tail>=head+1 && Count(q[tail-1],q[tail],x)) tail--;
q[++tail]=x;
}
void pop(int lim)
{
while(tail>=head+1 && q[head+1].y-q[head].y>lim*(q[head+1].x-q[head].x)) head++;
}
int mx;
void dfs(int x,int dep)
{
deep[dep]++;
mx=max(mx,dep);
for (int i=point[x];i;i=nxt[i])
{
int p = to[i];
dfs(p,dep+1);
}
}
int qq;
int main()
{
n=read();qq=read();
int ymh =0;
for (int i=1;i<=qq;i++) a[i]=read(),ymh=max(ymh,a[i]);
for (int i=2;i<=n;i++)
{
int x=read();
addedge(x,i);
}
dfs(1,1);
for (int i=mx;i>=0;i--)
{
deep[i]+=deep[i+1];
}
for (int i=0;i<mx;i++)
push((Point){i,deep[i+1],i});
for (register int i=1;i<=ymh;++i)
{
pop((-1)*i);
int now = q[head].num;
dp[i]=now+((deep[now+1]-1)/i)+1;
}
for (int i=1;i<=qq;i++) cout<<dp[a[i]]<<" ";
return 0;
}
洛谷3571 POI2014 SUP-Supercomputer (斜率优化)的更多相关文章
- 洛谷P2365 任务安排(斜率优化dp)
传送门 思路: 最朴素的dp式子很好考虑:设\(dp(i,j)\)表示前\(i\)个任务,共\(j\)批的最小代价. 那么转移方程就有: \[ dp(i,j)=min\{dp(k,j-1)+(sumT ...
- 洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP
做的第一道斜率优化\(DP\)QwQ 原题链接1/原题链接2 首先考虑\(O(n^2)\)的做法:设\(f[i]\)表示在\(i\)处建仓库的最小费用,则有转移方程: \(f[i]=min\{f[j] ...
- 【洛谷p3994】Highway 二分+斜率优化DP
题目大意:给你一颗$n$个点的有根树,相邻两个点之间有距离,我们可以从$x$乘车到$x$的祖先,费用为$dis\times P[x]+Q[x]$,问你除根以外每个点到根的最小花费. 数据范围:$n≤1 ...
- 洛谷P4027 [NOI2007]货币兑换(dp 斜率优化 cdq 二分)
题意 题目链接 Sol 解题的关键是看到题目里的提示... 设\(f[i]\)表示到第\(i\)天所持有软妹币的最大数量,显然答案为\(max_{i = 1}^n f[i]\) 转移为\(f_i = ...
- 洛谷P4072 [SDOI2016]征途(斜率优化)
传送门 推式子(快哭了……)$$s^2*m^2=\sum _{i=1}^m (x_i-\bar{x})^2$$ $$s^2*m^2=m*\sum _{i=1}^m x_i^2-2*sum_n\sum ...
- 【洛谷 P5017】 摆渡车(斜率优化)
题目链接 算是巩固了一下斜率优化吧. 设\(f[i]\)表示前\(i\)分钟最少等待时间. 则有\(f[i]=\min_{j=0}^{i-m}f[j]+(cnt[i]-cnt[j])*i-(sum[i ...
- 洛谷P4983 忘情 (WQS二分+斜率优化)
题目链接 忘情水二分模板题,最优解对划分段数的导数满足单调性(原函数凸性)即可使用此方法. 详细题解洛谷里面就有,不啰嗦了. 二分的临界点让人有点头大... #include<bits/stdc ...
- 洛谷4072 SDOI2016征途 (斜率优化+dp)
首先根据题目中给的要求,推一下方差的柿子. \[v\times m^2 = m\times \sum x^2 - 2 \times sum \times sum +sum*sum \] 所以\(ans ...
- 洛谷 P3580 - [POI2014]ZAL-Freight(单调队列优化 dp)
洛谷题面传送门 考虑一个平凡的 DP:我们设 \(dp_i\) 表示前 \(i\) 辆车一来一回所需的最小时间. 注意到我们每次肯定会让某一段连续的火车一趟过去又一趟回来,故转移可以枚举上一段结束位置 ...
随机推荐
- opencv入门系列教学(六)图像上的算术运算(加法、融合、按位运算)
0.序言 这一篇博客我们将学习图像的几种算术运算,例如加法,减法,按位运算等. 1.图像加法 我们可以通过OpenCV函数 cv.add() 或仅通过numpy操作 res=img1+img2 res ...
- 高德地图&兴趣点(poi)
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- D3之svg transform 与 css3 transform 区别与联系
D3就不用多介绍了,在数据可视化界属于大佬级别的js库.在这里主要想记录一下在写程序期间遇到的一个问题. 如下图所示,想完成主视图在小地图上的映射,小地图的白色矩形框用来代表当前主视图可见区域,主视图 ...
- MySQL——SQL语句入门
1.DDL: 数据库定义语言 定义对象:库.表 何为定义: 库的定义: 创建 删除 修改---->修改本身以及库中的对象(表.视图.函数.触发器...) 表的定义: 创建---->定义表的 ...
- 乐肴2.0环境改名后,需要删除原来的软链接(public/storage)
rm -rf public/storage php artisan storage:link
- .Net性能调优-MemoryPool
简单用法 //获取MemoryPool实例,实际返回了一个ArrayMemoryPool<T> MemoryPool<char> Pool = MemoryPool<ch ...
- Java环境搭建与HelloWprld—改变世界的第一步
1. JDK下载 访问oracle官网:http://www.oracle.com 在首页点击Downloads,进入oracle软件下载页. 在下载页面,点击Java. 选择Java (JDK) f ...
- 学习了解PHP中的SeasLog日志扩展
今天来学习的扩展是和日志相关的一个扩展,对于 PHP 的日志应用来说,除了本身自带的 error_log() . syslog() 之外,在大多数的框架中还会经常见到 monolog 的踪影.当然,我 ...
- JDBC-3(Transcation) ****
3.1 异常的使用说明 在工具类中(JDBCUtils)的方法最好声明异常(throws),以便后续实现类中去捕获这些异常. 工具类中捕获异常通常没有意义 eg:实现类中connection建立过程出 ...
- vue.js 配置axios 用来ajax请求数据
* 用npm 安装 axios 切换到项目的根目录 npm install --save axios vue-axios * 在vue的入口文件./src/main.js 中引入axios, 添加2行 ...