题意:给定带点权边权的树,定义路径的花费=路径边权和e+起点点权w[s]*终点点权w[t]。N<2e5,e,w<1e6;

思路:首先,需要树分治。 然后得到方程dp[i]=min{ dis[i]+dis[j]+w[i]*w[j] },很显然需要斜率优化。

注意维护凸包的时候是需要保证w[j]是单调的,这样才能用不等式维护队尾。  由于w[i]不是对应的队尾,所以我们还要二分凸包。

还有个问题,怎么确定我们得到的i和j不是在同一个子树呢? 因为如果在一颗子树的时候dp[i]=dis[i]+dis[j]+w[i]*w[j]-2*dis[LCA]。 其实没必要考虑这个问题,因为当LCA为根的时候会更新答案。(这一点想不到估计要很难去维护了)

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
int Laxt[maxn],Next[maxn],To[maxn],Len[maxn],cnt;
int sz[maxn],son[maxn],rt,all,vis[maxn],S[maxn],tot;
ll ans[maxn],a[maxn],dis[maxn],sum; int q[maxn],top;
bool cmp(int x,int y)
{
int xx=x,yy=y;
if(a[xx]==a[yy]) return dis[xx]<dis[yy];
return a[xx]<a[yy];
}
ll getans(int p,int k)
{
return dis[k]+dis[p]+a[p]*a[k];
}
void add(int u,int v,int w)
{
Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v; Len[cnt]=w;
}
void dfs1(int u,int f)
{
sz[u]=; son[u]=;
for(int i=Laxt[u];i;i=Next[i]){
if(To[i]!=f&&!vis[To[i]]) {
dfs1(To[i],u);
sz[u]+=sz[To[i]];
son[u]=max(son[u],sz[To[i]]);
}
}
son[u]=max(son[u],all-son[u]);
if(son[u]<son[rt]) rt=u;
}
void cal(int p)
{
if(top==) return ;int L=,R=top-,Mid;
ans[p]=min(ans[p],getans(p,q[top]));
while(L<=R){
Mid=(L+R)>>;
ll tmp1=getans(p,q[Mid]),tmp2=getans(p,q[Mid+]);
if(tmp1<tmp2) R=Mid-,ans[p]=min(ans[p],tmp1);
else L=Mid+,ans[p]=min(ans[p],tmp2);
}
}
void get(int u,int f)
{
cal(u);
for(int i=Laxt[u];i;i=Next[i])
if(To[i]!=f&&!vis[To[i]]) get(To[i],u);
}
bool check(int p){
return (dis[p]-dis[q[top]])*(a[p]-a[q[top-]])<=
(dis[p]-dis[q[top-]])*(a[p]-a[q[top]]);
}
void ADD(int p)
{
if(top&&a[p]==a[q[top]]&&dis[p]<dis[q[top]]) top--;
while(top>&&check(p)) top--;
q[++top]=p;
}
void get(int u,int f,ll D)
{
dis[u]=D; sz[u]=; S[++tot]=u;
for(int i=Laxt[u];i;i=Next[i])
if(To[i]!=f&&!vis[To[i]]){
get(To[i],u,D+Len[i]);
sz[u]+=sz[To[i]];
}
}
void solve(int u,int f)
{
vis[u]=; dis[u]=;
top=; tot=; S[++tot]=u;
for(int i=Laxt[u];i;i=Next[i]){
if(!vis[To[i]]&&To[i]!=f)
get(To[i],u,Len[i]);
}
sort(S+,S+tot+,cmp);
rep(i,,tot) ADD(S[i]);
rep(i,,tot) cal(S[i]);
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i];
if(!vis[v]&&v!=f) {
all=sz[v]; rt=;
dfs1(v,); solve(rt,);
}
}
}
int main()
{
int N,u,v,w;
scanf("%d",&N); son[]=N+;
rep(i,,N) scanf("%lld",&a[i]);
rep(i,,N) ans[i]=a[i]*a[i];
rep(i,,N-){
scanf("%d%d%d",&u,&v,&w);
add(u,v,w); add(v,u,w);
}
all=N; rt=;
dfs1(,); solve(rt,);
rep(i,,N) sum+=ans[i];
printf("%lld\n",sum);
return ;
}

Gym - 101002K:YATP (树分治+二分+斜率优化)的更多相关文章

  1. 【BZOJ4311】向量(线段树分治,斜率优化)

    [BZOJ4311]向量(线段树分治,斜率优化) 题面 BZOJ 题解 先考虑对于给定的向量集,如何求解和当前向量的最大内积. 设当前向量\((x,y)\),有两个不同的向量\((u1,v1),(u2 ...

  2. Codeforces Gym 101175F - Machine Works(CDQ 分治维护斜率优化)

    题面传送门 首先很明显我们会按照 \(d_i\) 的顺序从小到大买这些机器,故不管三七二十一先将所有机器按 \(d_i\) 从小到大排序. 考虑 \(dp\),\(dp_i\) 表示在时刻 \(d_i ...

  3. UOJ#7 NOI2014 购票 点分治+凸包二分 斜率优化DP

    [NOI2014]购票 链接:http://uoj.ac/problem/7 因为太麻烦了,而且暴露了我很多学习不扎实的问题,所以记录一下具体做法. 主要算法:点分治+凸包优化斜率DP. 因为$q_i ...

  4. 【洛谷p3994】Highway 二分+斜率优化DP

    题目大意:给你一颗$n$个点的有根树,相邻两个点之间有距离,我们可以从$x$乘车到$x$的祖先,费用为$dis\times P[x]+Q[x]$,问你除根以外每个点到根的最小花费. 数据范围:$n≤1 ...

  5. BZOJ 3672[NOI2014]购票(树链剖分+线段树维护凸包+斜率优化) + BZOJ 2402 陶陶的难题II (树链剖分+线段树维护凸包+分数规划+斜率优化)

    前言 刚开始看着两道题感觉头皮发麻,后来看看题解,发现挺好理解,只是代码有点长. BZOJ 3672[NOI2014]购票 中文题面,题意略: BZOJ 3672[NOI2014]购票 设f(i)f( ...

  6. LOJ 2353 & 洛谷 P4027 [NOI2007]货币兑换(CDQ 分治维护斜率优化)

    题目传送门 纪念一下第一道(?)自己 yy 出来的 NOI 题. 考虑 dp,\(dp[i]\) 表示到第 \(i\) 天最多有多少钱. 那么有 \(dp[i]=\max\{\max\limits_{ ...

  7. LOJ 2585 「APIO2018」新家 ——线段树分治+二分答案

    题目:https://loj.ac/problem/2585 算答案的时候要二分! 这样的话,就是对于询问位置 x ,二分出一个最小的 mid 使得 [ x-mid , x+mid ] 里包含所有种类 ...

  8. [NOI2007]货币兑换 cdq分治,斜率优化

    [NOI2007]货币兑换 LG传送门 妥妥的\(n \log n\)cdq做法. 这题用cdq分治也可以\(n \log n\)但是在洛谷上竟然比一些优秀的splay跑得慢真是见了鬼了看来还是人丑常 ...

  9. [NOI2007]货币兑换 「CDQ分治实现斜率优化」

    首先每次买卖一定是在某天 $k$ 以当时的最大收入买入,再到第 $i$ 天卖出,那么易得方程: $$f_i = \max \{\frac{A_iRate_kf_k}{A_kRate_k + B_k} ...

随机推荐

  1. 在Linux下面如何查看tomcat已经使用多少线程(Threads)

    先用 ps aux |grep tomcat 查看tomcat的 PID 再用 ps -T -p <PID>|wc -l 查看线程

  2. Ubuntu 16 修改时区!

    网上大部分解决办法是命令tzselect,然后选择亚洲-->中国->上海,但很遗憾,一点效果没有:后找到解决办法,运行命令dpkg-reconfigure tzdata,选择Asia--& ...

  3. Struts 2 初步入门(一)

    搭建Struts 2环境步骤 下载jar包----->创建web项目---->创建并完善相关配置文件---->创建action并测试启动 下载jar包访问网站:http://stru ...

  4. vs 编译库文件

    vs编译的库文件 静态库  debug和release版本 需要分开编译,我编译和实践的结果. 但是我也发现有的debug release都用同一个(搞不清楚). 然后添加到工程应用. 静态库  附件 ...

  5. Java Web(八) 事务,安全问题及隔离级别

    事务 什么是事务? 事务就是一组原子性的SQL查询,或者说是一个独立的工作单元. 事务的作用 事务在我们平常的CRUD(增删改查)操作当中也许不太常用, 但是如果我们有一种需求,一组操作中必须全部成功 ...

  6. 【Java算法】求质数的算法

    计算100以内的质数 1.质数:大于1的整数中,只能被自己和1整除的数为质数. 如果这个数,对比自己小1至2之间的数字,进行求余运算,结果都不等于0,则可以判断该数为质数. public class ...

  7. WPF技术实现控件截图

    1.http://www.cnblogs.com/TianFang/archive/2012/10/07/2714140.html 2.http://www.silverlightchina.net/ ...

  8. java.lang.UnsatisfiedLinkError:no dll in java.library.path

    报错:java.lang.UnsatisfiedLinkError:no dll in java.library.path 参考: Java调用Dll时,会出现no dll in java.libra ...

  9. Activity中通过标签获取当前Fragment

    初始化完成之后才有数据,否则获取不到 String tag = "android:switcher:"+viewPager.getId()+":"+viewPa ...

  10. 人生苦短,我用python,为什么选择python,python简介

    认识 Python 人生苦短,我用 Python —— Life is short, you need Python  目标 Python 的起源 为什么要用 Python? Python 的特点 ...