https://www.luogu.org/problemnew/show/CF1019E

题解

\[dis=day*a+b
\]

\[b=-day*a+dis
\]

然后就变成了斜率优化。

考虑边分治,每次把两边的凸包求出来。

然后再把两边的凸包做闵可夫斯基和求出新的凸包。

最后把分治求的的所有凸包上的点再做一次凸包即可得到答案凸包。

代码

#include<bits/stdc++.h>
#define N 200007
#define M 1000009
using namespace std;
typedef long long ll;
int head[N],tot=1,dp[N],sum,size[N],root,rootval,_rootval,top,n,m,num,cuu[2];
bool vis[N],jin[N<<1];
ll ans[M];
inline ll rd(){
ll x=0;char c=getchar();bool f=0;
while(!isdigit(c)){if(c=='-')f=1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return f?-x:x;
}
struct point{
double x,y;
inline point operator +(const point &b)const{return point{x+b.x,y+b.y};}
inline point operator -(const point &b)const{return point{x-b.x,y-b.y};}
inline double operator *(const point &b)const{return x*b.y-y*b.x;}
}cu[2][N],st[N*20];
inline double get_k(point y,point x){
return (y.y-x.y)/(y.x-x.x);
}
inline bool cmp(point a,point b){
if(a.x!=b.x)return a.x<b.x;
return a.y>b.y;
}
struct nd{int to,a,b;};
vector<nd>vec[N];
vector<point>pt,tp[2];
struct edge{
int n,to;
ll a,b;
}e[N<<1];
inline void add(int u,int v,int a,int b){
e[++tot].n=head[u];e[tot].to=v;head[u]=tot;e[tot].a=a;e[tot].b=b;
e[++tot].n=head[v];e[tot].to=u;head[v]=tot;e[tot].a=a;e[tot].b=b;
}
inline void get_tb(int tag,int num){
sort(cu[tag]+1,cu[tag]+num+1,cmp);
tp[tag].clear();
tp[tag].push_back(cu[tag][1]);
int top=1;
for(int i=2;i<=num;++i){
if(cu[tag][i].x==tp[tag][top-1].x)continue;
while(top>1&&get_k(cu[tag][i],tp[tag][top-2])>get_k(tp[tag][top-1],tp[tag][top-2]))tp[tag].pop_back(),top--;
tp[tag].push_back(cu[tag][i]);top++;
}
}
inline void merge(){
point now=tp[0][0]+tp[1][0];
pt.push_back(now);
int sm=tp[0].size()+tp[1].size()-2,now1=0,now2=0;
for(int i=1;i<=sm;++i){
point xx,yy;
if(now1+1<tp[0].size())xx=tp[0][now1+1]-tp[0][now1];
if(now2+1<tp[1].size())yy=tp[1][now2+1]-tp[1][now2];
if(now2+1>=tp[1].size()||((now1+1<tp[0].size())&&xx*yy<0))now=now+xx,now1++;
else now=now+yy,now2++;
pt.push_back(now);
}
}
void dfs1(int u,int fa){
int now=0;
for(vector<nd>::iterator it=vec[u].begin();it!=vec[u].end();++it){
int v=it->to,a=it->a,b=it->b;
if(v==fa)continue;
if(!now){add(u,v,a,b);now=u;}
else{++num;add(now,num,0,0);add(num,v,a,b);now=num;}
dfs1(v,u);
}
}
void getroot(int u,int fa){
size[u]=1;dp[u]=0;
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa&&!jin[i]){
int v=e[i].to;
getroot(v,u);
size[u]+=size[v];
if(max(size[v],sum-size[v])<rootval){
root=i;
rootval=max(size[v],sum-size[v]);
_rootval=size[v];
}
}
}
void getdeep(int u,int fa,int tag,ll suma,ll sumb){
bool tg=0;
for(int i=head[u];i;i=e[i].n)if(e[i].to!=fa&&!jin[i]){
int v=e[i].to;tg=1;
getdeep(v,u,tag,suma+e[i].a,sumb+e[i].b);
}
if(!tg){
cu[tag][++cuu[tag]]=point{suma,sumb};
}
}
void solve(int rot,int S){
int u=e[rot].to,v=e[rot^1].to;
jin[rot]=jin[rot^1]=1;
int sm1=_rootval,sm2=S-_rootval;
cuu[0]=cuu[1]=0;
getdeep(u,0,0,e[rot].a,e[rot].b);
getdeep(v,0,1,0ll,0ll);
get_tb(0,cuu[0]);
get_tb(1,cuu[1]);
merge();
if(sm1!=1){
sum=sm1;rootval=num;getroot(u,0);
solve(root,sm1);
}
if(sm2!=1){
sum=sm2;rootval=num;getroot(v,0);
solve(root,sm2);
}
}
int main(){
n=rd();m=rd();
if(n==1){
for(int i=1;i<=m;++i)printf("0 ");
return 0;
}
int x,y,a,b;
for(int i=1;i<n;++i){
x=rd();y=rd();a=rd();b=rd();
vec[x].push_back(nd{y,a,b});
vec[y].push_back(nd{x,a,b});
}
num=n;
dfs1(1,0);
root=0;sum=num;rootval=num;
getroot(1,0);
solve(root,num);
sort(pt.begin(),pt.end(),cmp);
for(vector<point>::iterator it=pt.begin();it!=pt.end();++it){
point now=*it;
if(!top){st[top=1]=now;continue;}
if(now.x==st[top].x)continue;
while(top>1&&get_k(now,st[top-1])>get_k(st[top],st[top-1]))top--;
st[++top]=now;
}
for(int i=m-1;i>=0;--i){
while(top>1&&get_k(st[top],st[top-1])<-i)top--;
ans[i]=1ll*i*st[top].x+st[top].y;
}
for(int i=0;i<m;++i)printf("%I64d ",ans[i]);
return 0;
}

CF1019E Raining season的更多相关文章

  1. Codeforces Round #503 (by SIS, Div. 1)E. Raining season

    题意:给一棵树每条边有a,b两个值,给你一个m,表示从0到m-1,假设当前为i,那么每条边的权值是a*i+b,求该树任意两点的最大权值 题解:首先我们需要维护出(a,b)的凸壳,对于每个i在上面三分即 ...

  2. ural 1250. Sea Burial

    1250. Sea Burial Time limit: 1.0 secondMemory limit: 64 MB There is Archipelago in the middle of a s ...

  3. 越狱Season 1- Episode 22: Flight

    Season 1, Episode 22: Flight -Franklin: You know you got a couple of foxes in your henhouse, right? ...

  4. 越狱Season 1-Episode 21: Go

    Season 1, Episode 21: Go -Michael: I need you to let me get us out of here. 我需要你帮我出去 -Patoshik: If y ...

  5. 越狱Season 1-Episode 20: Tonight

    Season 1, Episode 20: Tonight -Pope: I want him under 24hour surveillance. surveillance: 监视 保证24小时监视 ...

  6. 越狱Season 1-Episode 19: The Key

    Season 1, Episode 19: The Key -Kellerman: WeusedtohaveaGreatDane, Dane: 丹麦大狗 我们以前有一只大丹犬 bigandwild. ...

  7. 越狱Season 1- Episode 18: Bluff

    Season 1, Episode 18: Bluff -Michael: Scofield Scofield Michael Scofield Michael Scofield -Patoshik: ...

  8. 越狱Season 1-Episode 17: J-Cat

    Season 1, Episode 17: J-Cat -Pope: Hey, that's looking good. 嗨,看起来真棒 You're making some real progres ...

  9. 越狱Season 1- Episode 16

    Season 1, Episode 16 -Burrows:Don't be. It's not your fault. 不要,不是你的错 -Fernando: Know what I like? 知 ...

随机推荐

  1. 【linux开发】apt源设置

    不同的网络状况连接以下源的速度不同, 建议在添加前手动验证以下源的连接速度(ping下就行),选择最快的源可以节省大批下载时间. 首先备份源列表: sudo cp /etc/apt/sources.l ...

  2. C#读取xml节点数据方法小结

    本文实例总结了C#读取xml节点数据的方法.分享给大家供大家参考.具体如下: 第一种: 使用XPath XML的路径我配置在web.config 的appSettings节点下 <appSett ...

  3. 第八周作业总结&第六次实验报告

    实验六 Java异常 实验目的 理解异常的基本概念: 掌握异常处理方法及熟悉常见异常的捕获方法. 实验要求 练习捕获异常.声明异常.抛出异常的方法.熟悉try和catch子句的使用. 掌握自定义异常类 ...

  4. [DS+Algo] 002 一维表结构

    目录 1. 顺序表 1.1 分类 1.2 实现方式 1.3 扩容问题 1.4 操作 2. 链表 2.1 分类 2.2 链表相关操作 2.3 链表 VS 顺序表 3. 关于代码实现 1. 顺序表 1.1 ...

  5. 【Linux-驱动】驱动策略----信号量

    访问共享资源的代码区块叫“临界区”,临界区需要以某种互斥机制加以保护:自旋锁.信号量等.互斥访问:一个执行单元在访问共享资源的时候,其他的执行单元被禁止访问. 信号量:在Liunx中的信号量是一种睡眠 ...

  6. [19/09/16-星期一] Python的运算符和条件判断语句

    一.运算符 (1)算术运算符  + 加法运算符(如果是两个字符串之间进行加法运算,则会进行拼串操作) a = 10 + 5  计算 a = 'hello' + ' ' + 'world' 拼串  - ...

  7. 用了 10 多年的 Tomcat 居然有bug !

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 为了解决分布式链路追踪的问题,我们引入了实现OpenTracing的Jaeger来实现.然后我们为SpringBoot框架写 ...

  8. 01:django基础篇

    Django其他篇 目录: 1.1 django初探 1.2 第一个django项目 1.3 django render/redirect/HttpResponse 和 request.GET req ...

  9. go & flag

    参考 Golang下的flag模块使用 Go基础篇[第6篇]: 内置库模块 flag

  10. GitHub入门使用

    1.首先注册账号. 2.新建仓库. 3.安装GitBash 4.首先要在本地创建一个ssh key. $ ssh -keygen -t rsa -C "your email@.com&quo ...