Code Chef TSUM2(动态凸包+点分治)
题面
题解
真是毒瘤随机化算法居然一分都不给
首先这种树上的题目一般想到的都是点分
我们考虑如何统计经过当前点的路径的贡献,设当前点\(u\)在序列中是第\(c\)个,那么一条路径的贡献就是
\]
其中前面是从子树到\(u\)的路径,后面是从\(u\)到子树里的路径
然后拆一下
\]
如果我们把这看成一条直线,形如\(y=kx+b\),其中\(k=c\),\(b=\sum_{i=1}^k i\times w_{p_i}\),那么这就是要求我们对于处理所有从\(u\)到子树的路径中,令\(x=\sum\limits_{i=c+1}^kw_{p_i}\)最大的\(y\)(因为对于一条固定的路径来说\(\sum\limits_{i=c+1}^k (i-c)w_{p_i}\)是个常数)
那么现在问题就变成了动态插入直线,动态维护最大值。可以李超线段树也可以动态凸包
不过因为路径是有序的,所以对于儿子需要正着跑一遍,倒着跑一遍
话说为啥我到了现在还会打错点分啊喂……
鉴于这玩意儿太难码了我代码直接抄zyy的了
//minamoto
#include<bits/stdc++.h>
#define R register
#define ll long long
#define inline __inline__ __attribute__((always_inline))
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=1e5+5;const ll inf=(1ll<<60);
struct eg{int v,nx;}e[N<<1];int head[N],tot;
inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;}
bool qwq;
struct Line;typedef set<Line>::iterator IT;
struct Line{
ll k,b;mutable ll p;
inline Line(){}
inline Line(R ll kk,R ll bb,R ll pp):k(kk),b(bb),p(pp){}
inline bool operator <(const Line &b)const{return qwq?p<b.p:k<b.k;}
};
struct node{
multiset<Line>s;
bool inter(IT x,IT y){
if(y==s.end())return x->p=inf,0;
if(x->k==y->k)x->p=x->b>y->b?inf:-inf;
else x->p=(y->b-x->b)/(x->k-y->k);
return x->p>=y->p;
}
void ins(R ll k,R ll b){
IT it,z=s.insert(Line(k,b,0)),y=z++,x=y;
for(;inter(y,z);it=z,++z,s.erase(it));
if(x!=s.begin()&&inter(--x,y))it=y,++y,s.erase(it),inter(x,y);
for(;(y=x)!=s.begin()&&(--x)->p>=y->p;it=y,++y,s.erase(it),inter(x,y));
}
ll ask(R ll x){
qwq=1;IT res=s.lower_bound(Line(0,0,x));qwq=0;
return res==s.end()?-1e18:res->k*x+res->b;
}
};
int w[N],sz[N],mx[N],rt,size;ll res;bool vis[N];
int n;
void findrt(int u,int fa){
sz[u]=1,mx[u]=0;
go(u)if(!vis[v]&&v!=fa)findrt(v,u),sz[u]+=sz[v],cmax(mx[u],sz[v]);
cmax(mx[u],size-sz[u]);
if(mx[u]<mx[rt])rt=u;
}
void dfs1(int u,int fa,ll b,int d,ll x,node &s){
cmax(res,b+s.ask(x));
go(u)if(v!=fa&&!vis[v])dfs1(v,u,b+w[v]*(d+1),d+1,x+w[v],s);
}
void dfs2(int u,int fa,ll b,ll sum,int d,node &s){
s.ins(d,b);
go(u)if(v!=fa&&!vis[v])dfs2(v,u,b+sum+w[v],sum+w[v],d+1,s);
}
void solve(int u){
vis[u]=1;
static int st[N];int top=0;
node s1,s2;s1.ins(1,w[u]);
go(u)if(!vis[v]){
st[++top]=v;
dfs1(v,u,w[v],1,w[v],s1);
dfs2(v,u,w[v]+(w[u]<<1),w[v]+w[u],2,s1);
}
for(R int i=top,v;i&&(v=st[i]);--i){
dfs1(v,u,w[v],1,w[v],s2);
dfs2(v,u,w[v]+(w[u]<<1),w[v]+w[u],2,s2);
}
cmax(res,s2.ask(0)),cmax(res,1ll*w[u]);
int s=size;
go(u)if(!vis[v]){
rt=0,size=sz[v]>sz[u]?s-sz[u]:sz[v],findrt(v,0);
solve(rt);
}
}
int main(){
// freopen("testdata.in","r",stdin);
for(int T=read();T;--T){
n=read(),res=-inf;
fp(i,1,n)w[i]=read();
for(R int i=1,u,v;i<n;++i)u=read(),v=read(),add(u,v),add(v,u);
mx[0]=n+1,rt=0,size=n,findrt(1,0),solve(rt);
printf("%lld\n",res);
memset(head,0,(n+1)<<2);
memset(vis,0,n+1);
tot=0;
}
return 0;
}
Code Chef TSUM2(动态凸包+点分治)的更多相关文章
- Code Chef GEOCHEAT(凸包+旋转卡壳+随机化)
题面 传送门 题解 以下记\(S_i=\{1,2,3,...,i\}\) 我们先用凸包+旋转卡壳求出直径的长度,并记直径的两个端点为\(i,j\)(如果有多条直径随机取两个端点) 因为这个序列被\(r ...
- 【BZOJ 1701】Cow School(斜率优化/动态凸包/分治优化)
原题题解和数据下载 Usaco2007 Jan 题意 小牛参加了n个测试,第i个测试满分是\(p_i\),它的得分是\(t_i\).老师去掉\(t_i/p_i\)最小的d个测试,将剩下的总得分/总满分 ...
- 【BZOJ1492】【Luogu P4027】 [NOI2007]货币兑换 CDQ分治,平衡树,动态凸包
斜率在转移顺序下不满足单调性的斜率优化\(DP\),用动态凸包来维护.送命题. 简化版题意:每次在凸包上插入一个点,以及求一条斜率为\(K\)的直线与当前凸包的交点.思路简单实现困难. \(P.s\) ...
- [NOI2007]货币兑换Cash(DP+动态凸包)
第一次打动态凸包维护dp,感觉学到了超级多的东西. 首先,set是如此的好用!!!可以通过控制一个flag来实现两种查询,维护凸包和查找斜率k 不过就是重载运算符和一些细节方面有些恶心,90行解决 后 ...
- BZOJ [HAOI2011]防线修建(动态凸包)
听说有一种很高端的东西叫动态凸包维护dp就像学一下,不过介于本人还不会动态凸包就去学了下,还是挺神奇的说,维护上下凸包的写法虽然打得有点多不过也只是维护复制黏贴的事情而已罢了. 先说下动态凸包怎么写吧 ...
- 【BZOJ 2300】 2300: [HAOI2011]防线修建 (动态凸包+set)
2300: [HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上 ...
- BZOJ 2300: [HAOI2011]防线修建( 动态凸包 )
离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) --------------------------------------------------- ...
- Code Chef JUMP(递推+树状数组+李超线段树)
\(JUMP\) 很容易写出转移柿子 \[f_i=\min_{p_j<p_i}\{(h_i-h_j)^2+f_j\}+w_i\] 把\(\min\)里面的东西展开一下 \[f_j=\min_{p ...
- codeforces 70 D. Professor's task 动态凸包
地址:http://codeforces.com/problemset/problem/70/D 题目: D. Professor's task time limit per test 1 secon ...
随机推荐
- js深拷贝、浅拷贝
浅拷贝: 只针对当前对象的属性进行拷贝,若当前对象的属性是引用类型时,这个不考虑,不进行拷贝.若属性是引用类型,拷贝后引用的是地址,如果进行更改,会影响拷贝的原对象属性. 深拷贝:针对当前对象的数据的 ...
- Halcon开发环境和数据结构介绍——第1讲
1.Halcon是什么?如何初步了解Halcon? 这点我讲得不太好,不如给大家看看三个链接: ① Halcon官方网站:https://www.mvtec.com/products/halcon/ ...
- linux下xampp(apache)中配置域名访问,以及遇到的问题
xampp中apache使用域名访问 一.首先找到/opt/lampp/etc/httpd.conf: # Virtual hosts Include etc/extra/httpd-vhosts.c ...
- 关于前一篇innodb自增列自己的一点补充
上篇文章是我转载的,忘记注明了出处,在这里深感歉意.但是上篇文章中关于自增列预留ID的计算我当时怎么弄明白,后来自己想了想终于想通了,在这里详细解释一下. 我们以一次性插入10行为例,表格如下: 插 ...
- POJ1180 Batch Scheduling -斜率优化DP
题解 将费用提前计算可以得到状态转移方程: $F_i = \min(F_j + sumT_i * (sumC_i - sumC_j) + S \times (sumC_N - sumC_j)$ 把方程 ...
- 【UXPA大赛企业专访】Mockplus:“设计替代开发”将成为现实
“过去,是‘设计服务于开发’,现在,我认为是‘设计驱动开发’,而在不远的将来,随着AI的落地.大数据和云计算能力的提升,‘设计替代开发’将成为现实.Mockplus也正在为此部署并行动.” 近日,UX ...
- 8.15jsp document 头部声明 区别
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- PetaPoco与MySQL
随便写写的,PetaPoco与MySQL一起使用,在一个工控项目中充分使用节省不少开发时间,经历大半年的努力的项目接近完成,客户不认帐,开始需求合同就是个败笔,技术还是仅能解决技术问题而已! 上图上代 ...
- 2018.10.15 NOIP训练 hyc的等比数列(数论+枚举)
传送门 一道不错的枚举题. 显然桶排序之后瞎枚举一波. 考虑枚举首项和末项,假设首项除去一个最大的平方因子得到的结果为xxx. 那么末项一定等于xxx乘上一个平方数. 于是我们枚举首项,算出xxx然后 ...
- 第二章:冠词(Les articles)
★定冠词(Les articles définis ): 阳性单数:le(l') 阴性单数:la(l') 阴阳性复数:les ()表示前面已经提到的人或事物: ()有关的名词已被其它的成分(补语,关系 ...