CF1303G Sum of Prefix Sums
点分治+李超树
因为题目要求的是树上所有路径,所以用点分治维护
因为在点分治的过程中相当于将树上经过当前$root$的一条路径分成了两段
那么先考虑如何计算两个数组合并后的答案
记数组$a$,$b$,求得是将$b$数组接到$a$数组的答案
其$a$,$b$的sum of prefix sums分别为$sa$,$sb$,其中$a$数组所有元素的和为$sum$,$b$数组长度为$l$
然后整合一下原来计算的式
其实对于一个数组$P$的sum of prefix sums就是
$n*p_{1}+(n-1)*p_{2}+(n-2)*p_{3}+...+2*p_{n-1}+1*p_{n}$
照着这个式子推出来,将$b$数组接到$a$数组的答案是
$sa+sb+sum*l$
然后这里可以将$sa$看做截距,$sum$看做斜率,$l$为$x$坐标,最终答案为$y$坐标
求的就是每一个$sa$为截距,$sum$为斜率的线段在某一点的最大取值
那么用李超树维护即可
要注意对于树上两个节点$u$,$v$
$u$到$v$的答案和$v$到$u$的答案是不一样的
所以要在合并子树的时候要正着扫一遍,反着扫一遍
还有如果是只有一颗子树需要特判
1 #pragma GCC optimize(2)
2 #include <bits/stdc++.h>
3 #define int long long
4 using namespace std;
5 const int N=150100;
6 int n,a[N];
7 int sz[N],vi[N],dfn,MAX,root;
8 vector <int> e[N];
9 struct line
10 {
11 int k,b;
12 };
13 struct node
14 {
15 line tag;
16 int ti;
17 }sh[N*4];
18 int cal(int x,line a)
19 {
20 return a.k*x+a.b;
21 }
22 void change(int x,int l,int r,line k)
23 {
24 if (sh[x].ti!=dfn)
25 {
26 sh[x].tag=k;
27 sh[x].ti=dfn;
28 return;
29 }
30 if (cal(l,k)>=cal(l,sh[x].tag) && cal(r,k)>=cal(r,sh[x].tag))
31 {
32 sh[x].tag=k;
33 return;
34 }
35 if (cal(l,k)<=cal(l,sh[x].tag) && cal(r,k)<=cal(r,sh[x].tag))
36 return;
37 int mid=(l+r)>>1;
38 if (cal(mid,k)>cal(mid,sh[x].tag)) swap(k,sh[x].tag);
39 if (cal(l,k)>cal(l,sh[x].tag)) change(x+x,l,mid,k);
40 else change(x+x+1,mid+1,r,k);
41 }
42 int query(int x,int l,int r,int wh)
43 {
44 int ans=(sh[x].ti==dfn)?cal(wh,sh[x].tag):0;
45 if (l==r) return ans;
46 int mid=(l+r)>>1;
47 if (wh<=mid) ans=max(ans,query(x+x,l,mid,wh));
48 else ans=max(ans,query(x+x+1,mid+1,r,wh));
49 return ans;
50 }
51 //李超树
52 void dfs_insert(int x,int fa,int de,line now)
53 {
54 now.k+=a[x];
55 now.b+=de*a[x];
56 change(1,1,n,now);
57 for (register int i=0;i<(int)e[x].size();i++)
58 {
59 int u=e[x][i];
60 if (vi[u] || u==fa) continue;
61 dfs_insert(u,x,de+1,now);
62 }
63 }
64 void dfs_query(int x,int fa,int de,int sb,int s)
65 {
66 sb+=a[x]+s;
67 s+=a[x];
68 MAX=max(MAX,query(1,1,n,de)+sb);
69 for (register int i=0;i<(int)e[x].size();i++)
70 {
71 int u=e[x][i];
72 if (vi[u] || u==fa) continue;
73 dfs_query(u,x,de+1,sb,s);
74 }
75 }
76 void dfs_size(int x,int fa)
77 {
78 sz[x]=1;
79 for (register int i=0;i<(int)e[x].size();i++)
80 {
81 int u=e[x][i];
82 if (vi[u] || u==fa) continue;
83 dfs_size(u,x);
84 sz[x]+=sz[u];
85 }
86 }
87 void dfs_root(int x,int fa,int tot)
88 {
89 bool bl=1;
90 for (register int i=0;i<(int)e[x].size();i++)
91 {
92 int u=e[x][i];
93 if (vi[u] || u==fa) continue;
94 dfs_root(u,x,tot);
95 if (sz[u]>tot/2) bl=0;
96 }
97 if (tot-sz[x]>tot/2) bl=0;
98 if (bl) root=x;
99 }
100 void dfs(int x,int fa,int de,int sa,int sb,int s)
101 {
102 sa+=de*a[x];
103 sb+=s+a[x];
104 s+=a[x];
105 MAX=max(MAX,sb);
106 MAX=max(MAX,sa);
107 for (register int i=0;i<(int)e[x].size();i++)
108 {
109 int u=e[x][i];
110 if (vi[u] || u==fa) continue;
111 dfs(u,x,de+1,sa,sb,s);
112 }
113 }
114 void divide(int x)//点分治
115 {
116 dfn++;
117 vi[x]=1;
118 int cnt=0;
119 for (register int i=0;i<(int)e[x].size();i++)
120 {
121 int u=e[x][i];
122 if (vi[u]) continue;
123 cnt++;
124 line tmp;
125 tmp.k=tmp.b=0;
126 if (cnt!=1) dfs_query(u,x,2,a[x],a[x]);
127 dfs_insert(u,x,1,tmp);
128 }
129 bool bl=(cnt==1);
130 dfn++;cnt=0;
131 for (register int i=(int)e[x].size()-1;i>=0;i--)//反着扫描
132 {
133 int u=e[x][i];
134 if (vi[u]) continue;
135 if (bl) dfs(u,x,2,a[x],a[x],a[x]);//只有一颗子树时的特判
136 cnt++;
137 line tmp;
138 tmp.k=tmp.b=0;
139 if (cnt!=1) dfs_query(u,x,2,a[x],a[x]);
140 dfs_insert(u,x,1,tmp);
141 }
142 for (register int i=0;i<(int)e[x].size();i++)
143 {
144 int u=e[x][i];
145 if (vi[u]) continue;
146 dfs_size(u,x);
147 dfs_root(u,x,sz[u]);
148 divide(root);
149 }
150 }
151 signed main()
152 {
153 scanf("%lld",&n);
154 for (int i=1;i<n;i++)
155 {
156 int u,v;
157 scanf("%lld%lld",&u,&v);
158 e[u].push_back(v);
159 e[v].push_back(u);
160 }
161 for (int i=1;i<=n;i++)
162 {
163 scanf("%lld",&a[i]);
164 MAX=max(MAX,a[i]);
165 }
166 dfs_size(1,-1);
167 dfs_root(1,-1,sz[1]);
168 divide(root);
169 printf("%lld\n",MAX);
170 }
CF1303G Sum of Prefix Sums的更多相关文章
- [CF1303G] Sum of Prefix Sums - 点分治,李超线段树
给定一棵 \(n\) 个点的带点权的树,求树上的路径 \(x_1,...,x_k\) ,最大化 \(\sum_{i=1}^k ia_{x_i}\) Solution 树上路径问题可用点分治. 考虑如何 ...
- Codeforces 1303G - Sum of Prefix Sums(李超线段树+点分治)
Codeforces 题面传送门 & 洛谷题面传送门 个人感觉这题称不上毒瘤. 首先看到选一条路径之类的字眼可以轻松想到点分治,也就是我们每次取原树的重心 \(r\) 并将路径分为经过重心和不 ...
- CodeForces 837F - Prefix Sums | Educational Codeforces Round 26
按tutorial打的我血崩,死活挂第四组- - 思路来自FXXL /* CodeForces 837F - Prefix Sums [ 二分,组合数 ] | Educational Codeforc ...
- Educational Codeforces Round 26 [ D. Round Subset ] [ E. Vasya's Function ] [ F. Prefix Sums ]
PROBLEM D - Round Subset 题 OvO http://codeforces.com/contest/837/problem/D 837D 解 DP, dp[i][j]代表已经选择 ...
- 【题解】【数组】【Prefix Sums】【Codility】Genomic Range Query
A non-empty zero-indexed string S is given. String S consists of N characters from the set of upper- ...
- 【题解】【数组】【Prefix Sums】【Codility】Passing Cars
A non-empty zero-indexed array A consisting of N integers is given. The consecutive elements of arra ...
- Codeforces 837F Prefix Sums
Prefix Sums 在 n >= 4时候直接暴力. n <= 4的时候二分加矩阵快速幂去check #include<bits/stdc++.h> #define LL l ...
- CodeForces 1204E"Natasha, Sasha and the Prefix Sums"(动态规划 or 组合数学--卡特兰数的应用)
传送门 •参考资料 [1]:CF1204E Natasha, Sasha and the Prefix Sums(动态规划+组合数) •题意 由 n 个 1 和 m 个 -1 组成的 $C_{n+m} ...
- codeforces:Prefix Sums分析和实现
题目大意: 给出一个函数P,P接受一个数组A作为参数,并返回一个新的数组B,且B.length = A.length + 1,B[i] = SUM(A[0], ..., A[i]).有一个无穷数组序列 ...
随机推荐
- 【Hadoop】伪分布式安装
创建hadoop用户 创建用户命令: sudo useradd -m hadoop -s /bin/bash 创建好后需要更改hadoop用户的密码,命令如下: sudo passwd hadoop ...
- 《To B产品经理进阶》
一.沙漏哟:To B产品技术标准化(全网独家) 经济机器是怎样运行的(超级简单模式理解经济运行规律) <俞军产品方法论>(思维模型.交易模型.经济学.心理学) <深度思考六步法> ...
- 草率了,又一个Maven打包的问题
经常遇到 Maven 相关的问题,这是之前的文章: 这个 Maven 依赖的问题,你敢说你没遇到过:https://mp.weixin.qq.com/s/SzBbDtyRUrk_7LH8SUbGXQ ...
- 持续集成工具之Jenkins使用配置
在上一篇博客中,我们主要介绍了DevOps理念以及java环境和jenkins的安装,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13805666.html: ...
- Redis安装使用以及可能的算法实践
layout: post title: 2017-12-05-Redis 入门 tags: - Redis - 实时特征 - UCB, Tompson sampling Redis 是什么? Redi ...
- 【LWJGL3】LWJGL3的内存分配设计,第一篇,栈上分配
简介 LWJGL (Lightweight Java Game Library 3),是一个支持OpenGL,OpenAl,Opengl ES,Vulkan等的Java绑定库.<我的世界> ...
- Jmeter之接口依赖
一.应用场景 1.现在有两个接口,一个是登录,一个查询,但查询接口必须要依赖登录接口的token,那么通过正则表达式提取器提取登录接口的响应结果 2.现在有两个接口,A接口返回列表数据,另一个查询接口 ...
- docker-阿里云加速
系统版本 centos7 阿里云登录 ->容器镜像服务->镜像加速器 复制下面的直接执行即可 sudo mkdir -p /etc/docker sudo tee /etc/doc ...
- centos8安装及配置nfs4
一,用rpm检查是否有nfs-utils的包已安装 [root@localhost liuhongdi]# rpm -qa | grep nfs-utils nfs-utils-2.3.3-26.el ...
- Mac下面 matplotlib 中文无法显示解决
一.环境描述 python 3.7 mac 10.14.5 二.问题描述 如下图所示,当使用matplotlib绘制图片的时候,所有的中文字符无法正常显示. 三.解决方法 1.下载字体ttf文件 链接 ...