【BZOJ2870】最长道路tree 点分治+树状数组
【BZOJ2870】最长道路tree
Description
Input
Output
Sample Input
5 3 5
1 2
1 3
Sample Output
【样例解释】
选择从1到3的路径,痛苦程度为min(5,5)*2=10
HINT
100%的数据n<=50000
其中有20%的数据树退化成一条链
所有数据点权<=65536
Hint:建议答案使用64位整型
题解:我们采用树形DP版本的点分治。对于当前的分治中心x,我们依次遍历它的每个儿子的子树,每访问到一个点y,我们记录y到x路径上的权值最小值min和长度len,然后在树状数组中找到:在以前的子树中,min>=当前min的len的最大值,然后用min*(len+当前len)更新答案。
这样正着反着做两遍即可。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=50010;
typedef long long ll;
int n,m,cnt,now,tot,mn,rt;
int to[maxn<<1],next[maxn<<1],head[maxn],siz[maxn],v[maxn],s[70000],vis[maxn],tim[70000],p[maxn];
ll ans;
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void getrt(int x,int fa)
{
siz[x]=1;
int i,tmp=0;
for(i=head[x];i!=-1;i=next[i]) if(!vis[to[i]]&&to[i]!=fa) getrt(to[i],x),siz[x]+=siz[to[i]],tmp=max(tmp,siz[to[i]]);
tmp=max(tmp,tot-siz[x]);
if(tmp<mn) rt=x,mn=tmp;
}
inline int query(int x)
{
x++;
int i,ret=0;
for(i=x;i<=m;i+=i&-i)
{
if(tim[i]<now) tim[i]=now,s[i]=0;
ret=max(ret,s[i]);
}
return ret;
}
inline void updata(int x,int val)
{
x++;
for(int i=x;i;i-=i&-i)
{
if(tim[i]<now) tim[i]=now,s[i]=0;
s[i]=max(s[i],val);
}
}
void ask(int x,int fa,int dep,int sn)
{
sn=min(sn,v[x]),ans=max(ans,(ll)(dep+query(sn))*sn);
for(int i=head[x];i!=-1;i=next[i]) if(!vis[to[i]]&&to[i]!=fa) ask(to[i],x,dep+1,sn);
}
void change(int x,int fa,int dep,int sn)
{
sn=min(sn,v[x]),updata(sn,dep);
for(int i=head[x];i!=-1;i=next[i]) if(!vis[to[i]]&&to[i]!=fa) change(to[i],x,dep+1,sn);
}
void solve(int x)
{
vis[x]=1;
int i;
now++,p[0]=0;
for(i=head[x];i!=-1;i=next[i]) if(!vis[to[i]]) p[++p[0]]=to[i];
for(i=1;i<=p[0];i++) ask(p[i],x,2,v[x]),change(p[i],x,1,v[x]);
now++;
for(i=p[0];i>=1;i--) ask(p[i],x,2,v[x]),change(p[i],x,1,v[x]);
for(i=head[x];i!=-1;i=next[i]) if(!vis[to[i]]) tot=siz[to[i]],mn=1<<30,getrt(to[i],x),solve(rt);
}
inline void add(int a,int b)
{
to[cnt]=b,next[cnt]=head[a],head[a]=cnt++;
}
int main()
{
n=rd();
int i,a,b;
for(i=1;i<=n;i++) v[i]=rd(),m=max(m,v[i]+1);
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),add(a,b),add(b,a);
tot=n,mn=1<<30,ans=m-1,getrt(1,0),solve(rt);
printf("%lld",ans);
return 0;
}
【BZOJ2870】最长道路tree 点分治+树状数组的更多相关文章
- bzoj2870最长道路tree——边分治
简化版描述: 给定一棵N个点的树,求树上一条链使得链的长度乘链上所有点中的最小权值所得的积最大. 其中链长度定义为链上点的个数. 有几个不同的做法: 1.sort+并查集+树的直径.边从大到小加入 ...
- 【BZOJ4553】[Tjoi2016&Heoi2016]序列 cdq分治+树状数组
[BZOJ4553][Tjoi2016&Heoi2016]序列 Description 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他.玩具上有一个数列,数列中某些项的值可能 ...
- 【bzoj2225】[Spoj 2371]Another Longest Increasing CDQ分治+树状数组
题目描述 给定N个数对(xi, yi),求最长上升子序列的长度.上升序列定义为{(xi, yi)}满足对i<j有xi<xj且yi<yj. 样例输入 8 1 3 3 2 1 1 4 5 ...
- BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组
BZOJ_2253_[2010 Beijing wc]纸箱堆叠 _CDQ分治+树状数组 Description P 工厂是一个生产纸箱的工厂.纸箱生产线在人工输入三个参数 n p a , , 之后, ...
- BZOJ_2225_[Spoj 2371]Another Longest Increasing_CDQ 分治+树状数组
BZOJ_2225_[Spoj 2371]Another Longest Increasing_CDQ 分治+树状数组 Description 给定N个数对(xi, yi),求最长上升子 ...
- LOJ3146 APIO2019路灯(cdq分治+树状数组)
每个时刻都形成若干段满足段内任意两点可达.将其视为若干正方形.则查询相当于求历史上某点被正方形包含的时刻数量.并且注意到每个时刻只有O(1)个正方形出现或消失,那么求出每个矩形的出现时间和消失时间,就 ...
- BZOJ_3262_陌上花开_CDQ分治+树状数组
BZOJ_3262_陌上花开_CDQ分治+树状数组 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),用三个整数表示. 现在要对每朵花评级,一朵花的级别是它拥有的 ...
- BZOJ 1176 Mokia CDQ分治+树状数组
1176: [Balkan2007]Mokia Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1854 Solved: 821[Submit][St ...
- 【bzoj3262】陌上花开 CDQ分治+树状数组
题目描述 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A比另一朵花B要美丽,当且仅当Sa&g ...
随机推荐
- Java8 对多个异步任务进行流水线操作(笔记)
现在我们要对商店商品进行折扣服务.每个折扣代码对应不同的折扣率,使用一个枚举变量Discount.Code来实现这一想法,具体代码如下所示. 以枚举类型定义的折扣代码 /** * 折扣服务api * ...
- .Net 下未捕获异常的处理
原地址:http://www.cnblogs.com/eaglet/archive/2009/02/17/1392191.html .Net 下未捕获异常的处理 作者:Eaglet 随着.Net技术的 ...
- homestead虚拟机,通过npm下载依赖包和解决运行gulp报错问题 yarn出错问题
homestead虚拟机,通过npm下载依赖包和解决运行gulp报错问题 yarn出错问题 1. 在虚拟器运行 npm 下载依赖组件时报错: npm ERR! EPROTO: protocol err ...
- app接口开发(php)
1.JSON方式封装通信接口: 封装: response.php <?php // JSON方式封装通信接口 // 定义 response类 class Response { // 定义一个静态 ...
- 《深入理解Nginx:模块开发与架构解析》(一)
第1章 研究 Nginx 前的准备工作 1.1 Nginx 是什么 Web 服务器的基本功能:基于 REST 架构风格,以统一资源描述符(URI)或者统一资源定位符(URL),作为沟通依据,通过 HT ...
- Azure Storage 分块上传
概述 Azure 存储提供三种类型的 Blob:块 Blob.页 Blob 和追加 Blob.其中,块 Blob 特别适用于存储短的文本或二进制文件,例如文档和媒体文件. 块 Blob 由块组成,每个 ...
- nodejs 命令行交互
人机交互 function readSyncByfs(tips) { tips = tips || '> '; process.stdout.write(tips); process.stdin ...
- SSRS 浮动表头设置
报表的Header部分,在出现分页或者多页的时候仍然会在其他页显示,但是在报表的Body中如果使用Tablix(矩阵)时,行/列标题翻页时候并没有保持固定.解决办法: (1): 左键单击矩阵(Tabl ...
- Java并发编程(十三)同步容器类
同步容器类 Vector.HashTable,我用的很少:Vecotr的实现和ArrayList挺接近的,不同的是Vector中很多的方法都用synchronized进行了同步.在不强调线程安全地时候 ...
- \sum的写法
\sum默认上下标是写在右上角和右下角的.在独立公式中,则是写在上面和下面的.对于行内公式,我们也可以强制用\limits让其上下表标出现在上面和下面.Note:\sum\nolimits的作用相当于 ...