题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2870

关于边分治:https://www.cnblogs.com/Khada-Jhin/p/10154994.html

自己写了那种把一个孩子连向自己,其他孩子连新建节点的重构图方法。

如果 vector 里最后一个元素恰好是父亲的话,末尾就会有一个新建节点只有一个孩子。

solve( ) 完之后要继续 get_rt( ) ,想知道两边的点数 ts ;可以发现 to[ cr ] 的部分点数恰好是 siz[ to[ cr ] ] ,另一部分就是 s - siz[ to[ cr ] ] 了。

要递归的时候,如果 ts == 1 ,就不递归了。

关于这道题:https://www.cnblogs.com/Miracevin/p/10430192.html

虚点的点权就是它建出它的那个实点的点权;路径上的点数等于路径上的实边条数 + 1 。

找出两边的路径,分别 sort 然后双指针即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define pb push_back
#define ll long long
using namespace std;
int rdn()
{int ret=0;bool fx=1;char ch=getchar();while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();return fx?ret:-ret;
}
ll Mx(ll a,ll b){return a>b?a:b;}
ll Mn(ll a,ll b){return a<b?a:b;}
const int N=5e4+5,M=N<<1,INF=7e4;
int n,vl[M],hd[M],xnt=1,to[M<<1],nxt[M<<1],w[M<<1];//xnt=1
int siz[M],mn,Rt,tot[2]; bool vis[M]; ll ans;
vector<int> vt[N];
struct Node{int dis,mn;Node(int d=0,int m=0):dis(d),mn(m) {}bool operator< (const Node &b)const{return mn<b.mn;}
}a[2][M];
void add(int x,int  y,int z)
{to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt;w[xnt]=z;to[++xnt]=x;nxt[xnt]=hd[y];hd[y]=xnt;w[xnt]=z;
}
void Rbuild(int cr,int fa)
{for(int i=0,lm=vt[cr].size()-1,v,lst=0;i<=lm;i++){if((v=vt[cr][i])==fa)continue;if(!lst) add(cr,v,1), lst=cr;else if(i==lm) add(lst,v,1);else {n++; vl[n]=vl[cr];add(lst,n,0); add(n,v,1); lst=n;}}for(int i=0,lm=vt[cr].size(),v;i<lm;i++)if((v=vt[cr][i])!=fa)Rbuild(v,cr);
}
void get_rt(int cr,int fa,int s)
{siz[cr]=1;for(int i=hd[cr],v,d;i;i=nxt[i])if(!vis[i>>1]&&(v=to[i])!=fa){get_rt(v,cr,s); siz[cr]+=siz[v];d=Mx(siz[v],s-siz[v]);if(d<mn)mn=d, Rt=i;}
}
void dfs(int cr,int fa,int lj,int mn,bool fx)
{mn=Mn(mn,vl[cr]); a[fx][++tot[fx]]=Node(lj,mn);for(int i=hd[cr],v;i;i=nxt[i])if(!vis[i>>1]&&(v=to[i])!=fa)dfs(v,cr,lj+w[i],mn,fx);
}
void cz()
{for(int i=0;i<=1;i++)sort(a[i]+1,a[i]+tot[i]+1);int p0=tot[1]+1, lj=0, tw=w[Rt]+1;//+1for(int i=tot[0];i;i--){int tmn=a[0][i].mn;while(p0>1&&a[1][p0-1].mn>=tmn)p0--, lj=Mx(lj,a[1][p0].dis);if(p0>tot[1])continue;//
      ans=Mx(ans,(ll)tmn*(lj+a[0][i].dis+tw));}p0=tot[0]+1; lj=0;for(int i=tot[1];i;i--){int tmn=a[1][i].mn;while(p0>1&&a[0][p0-1].mn>=tmn)p0--, lj=Mx(lj,a[0][p0].dis);if(p0>tot[0])continue;//
      ans=Mx(ans,(ll)tmn*(lj+a[1][i].dis+tw));}
}
void solve(int cr,int s)
{vis[cr>>1]=1;tot[0]=tot[1]=0;dfs(to[cr],0,0,INF,0); dfs(to[cr^1],0,0,INF,1);cz();int v=to[cr], ts=siz[v];if(ts>1){mn=N; get_rt(v,0,ts); solve(Rt,ts);}ts=s-ts; v=to[cr^1];// s-ts not s-siz[v] for siz[v] may changed!!!if(ts>1){mn=N; get_rt(v,0,ts); solve(Rt,ts);}
}
int main()
{n=rdn();for(int i=1;i<=n;i++)vl[i]=rdn();for(int i=1,u,v;i<n;i++){u=rdn();v=rdn(); vt[u].pb(v); vt[v].pb(u);}Rbuild(1,0);mn=N;get_rt(1,0,n);solve(Rt,n);printf("%lld\n",ans);return 0;
}

转载于:https://www.cnblogs.com/Narh/p/10457963.html

bzoj 2870 最长道路tree——边分治相关推荐

  1. bzoj 2870: 最长道路tree

    orz n+e的题解 显然,将两棵树合并以后,新直径的两个端点一定在原来的两条直径的四个端点中. 画个图就知道了(我竟然没看出来QAQ 于是就可以从大到小枚举最小权,并查集合并了 时间复杂度\(O(n ...

  2. bzoj2870. 最长道路tree【点分治】【边分治】

    传送门 HHH 城很大,有NNN个路口(从111到NNN编号),路口之间有N−1N-1N−1边,使得任意两个路口都能互相到达,这些道路的长度我们视作一样.每个路口都有很多车辆来往,所以每个路口i都有一 ...

  3. 线段树合并与分裂维护树上最长上升子序列 + 点分治删点 ---- 2021 牛客多校第一场 C - Cut the tree(详解)

    题目大意: 给你一个树,树上每个点都有一个权值valnodeval_{node}valnode​,路径(u,v)(u,v)(u,v) 上所有点按顺序有序序列,令f(u,v)f(u,v)f(u,v)是这 ...

  4. bzoj 1468 Tree(点分治模板)

    1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MB Submit: 1527  Solved: 818 [Submit][Status][Discus ...

  5. Bzoj4016/洛谷P2993 [FJOI2014] 最短路径树问题(最短路径问题+长链剖分/点分治)

    题面 Bzoj 洛谷 题解 首先把最短路径树建出来(用\(Dijkstra\),没试过\(SPFA\)\(\leftarrow\)它死了),然后问题就变成了一个关于深度的问题,可以用长链剖分做,所以我 ...

  6. Codeforces Round #507 (Div. 1) D. You Are Given a Tree 根号分治 + dp

    传送门 题意: 有一颗nnn个节点的树,其中一个简单路径集合被称为kkk合法当且仅当: 树的每个节点至多属于一条路径,且每条路径恰好包含kkk个点. 对于k∈[1,n]k\in [1,n]k∈[1,n ...

  7. [luogu 4292][bzoj 1758][WC2010] 重建计划(点分治 + dp + 单调队列优化 + 启发式合并)

    [WC2010]重建计划 problem solution code problem 洛谷指路 solution 一看那个道路平均价值的式子:AvgValue=∑e∈Sv(e)∣S∣\text{Avg ...

  8. BZOJ.4738.[清华集训2016]汽水(点分治 分数规划)

    BZOJ UOJ 记\(val_i\)是每条边的边权,\(s\)是边权和,\(t\)是经过边数,\(k\)是给定的\(k\). 在点分治的时候二分答案\(x\),设\(|\frac st-k|=x\) ...

  9. 【CodeForces】914 E. Palindromes in a Tree 点分治

    [题目]E. Palindromes in a Tree [题意]给定一棵树,每个点都有一个a~t的字符,一条路径回文定义为路径上的字符存在一个排列构成回文串,求经过每个点的回文路径数.n<=2 ...

最新文章

  1. Http请求之优雅的RestTemplate
  2. python使用ctype中”OSError: [WinError 193] %1 不是有效的 Win32 应用程序“的解决办法
  3. 致开发者:2018年AI技术趋势展望
  4. 人本质要好,要善良,要真诚,有格局和胸怀,有能力,有眼光,能讲故事,能找到人,能搞到钱...
  5. php数据仓库数据分析,利用Apache+PHP+MySql构建数据仓库
  6. 三步修改CodeBlocks主题
  7. long long or int
  8. Xamarin中使用DatePickerDialog的相关问题
  9. .NET 排序 Array.Sort<T> 实现分析
  10. “System.AccessViolationException”类型的未经处理的异常在 System.Data.dll 中发生
  11. LeetCode Maximum Product Subarray 解题报告
  12. DOS命令大全(经典收藏)【运行CMD后的命令】
  13. 怎样设置电脑壁纸_怎样把C盘设置成禁止安装任何软件?教你两个方法,告别电脑卡顿...
  14. 设计一个小型的物联网应用系统_点赞 | 面向能源物联网的智能传感芯片设计与应用...
  15. Phpstorm调试详解(包含命令行以及浏览器)
  16. java基于Android校园购物商城小超市
  17. html支付选择银行卡,JQ电脑手机通用银行选择下拉框 提现银行卡绑定
  18. 顺序结构——有关圆的计算
  19. 超声系统前端理论与模拟仿真
  20. mysql修改主键自增长时报错

热门文章

  1. 邮件附件在线预览——HTML Filter
  2. jquery页面加载的时候加载函数
  3. iphone内存检测
  4. [原创]按键小精灵9通用去广告破解补丁
  5. QQ牧场在高速模式下的一些小bug
  6. 【转】为什么有天线的路由器信号还不如没有天线的路由
  7. C语言库函数的实战之一
  8. hdu 5077 NAND(打表)2014 Asia regional 鞍山站 H题
  9. 【Java8精华教程】一起爪哇Java8——好用的Stream
  10. rhel6多台主机的HA集群,并实现增加仲裁盘和共享存储