Code Chef TSUM2(动态凸包+点分治)

时间:2023-02-15 15:48:30

题面

传送门

题解

真是毒瘤随机化算法居然一分都不给

首先这种树上的题目一般想到的都是点分

我们考虑如何统计经过当前点的路径的贡献,设当前点\(u\)在序列中是第\(c\)个,那么一条路径的贡献就是

\[Ans=\sum_{i=1}^k i\times w_{p_i}=\sum_{i=1}^ci\times w_{p_i}+\sum_{i=c+1}^ki\times w_{p_i}
\]

其中前面是从子树到\(u\)的路径,后面是从\(u\)到子树里的路径

然后拆一下

\[Ans=c\times \sum_{i=c+1}^kw_{p_i}+\sum_{i=c+1}^k (i-c)w_{p_i}+\sum_{i=1}^k i\times w_{p_i}
\]

如果我们把这看成一条直线,形如\(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(动态凸包+点分治)的更多相关文章

  1. Code Chef GEOCHEAT(凸包&plus;旋转卡壳&plus;随机化)

    题面 传送门 题解 以下记\(S_i=\{1,2,3,...,i\}\) 我们先用凸包+旋转卡壳求出直径的长度,并记直径的两个端点为\(i,j\)(如果有多条直径随机取两个端点) 因为这个序列被\(r ...

  2. 【BZOJ 1701】Cow School(斜率优化&sol;动态凸包&sol;分治优化)

    原题题解和数据下载 Usaco2007 Jan 题意 小牛参加了n个测试,第i个测试满分是\(p_i\),它的得分是\(t_i\).老师去掉\(t_i/p_i\)最小的d个测试,将剩下的总得分/总满分 ...

  3. 【BZOJ1492】【Luogu P4027】 &lbrack;NOI2007&rsqb;货币兑换 CDQ分治,平衡树,动态凸包

    斜率在转移顺序下不满足单调性的斜率优化\(DP\),用动态凸包来维护.送命题. 简化版题意:每次在凸包上插入一个点,以及求一条斜率为\(K\)的直线与当前凸包的交点.思路简单实现困难. \(P.s\) ...

  4. &lbrack;NOI2007&rsqb;货币兑换Cash(DP&plus;动态凸包)

    第一次打动态凸包维护dp,感觉学到了超级多的东西. 首先,set是如此的好用!!!可以通过控制一个flag来实现两种查询,维护凸包和查找斜率k 不过就是重载运算符和一些细节方面有些恶心,90行解决 后 ...

  5. BZOJ &lbrack;HAOI2011&rsqb;防线修建(动态凸包)

    听说有一种很高端的东西叫动态凸包维护dp就像学一下,不过介于本人还不会动态凸包就去学了下,还是挺神奇的说,维护上下凸包的写法虽然打得有点多不过也只是维护复制黏贴的事情而已罢了. 先说下动态凸包怎么写吧 ...

  6. 【BZOJ 2300】 2300&colon; &lbrack;HAOI2011&rsqb;防线修建 (动态凸包&plus;set)

    2300: [HAOI2011]防线修建 Description 近来A国和B国的矛盾激化,为了预防不测,A国准备修建一条长长的防线,当然修建防线的话,肯定要把需要保护的城市修在防线内部了.可是A国上 ...

  7. BZOJ 2300&colon; &lbrack;HAOI2011&rsqb;防线修建&lpar; 动态凸包 &rpar;

    离线然后倒着做就变成了支持加点的动态凸包...用平衡树维护上凸壳...时间复杂度O(NlogN) --------------------------------------------------- ...

  8. Code Chef JUMP(递推&plus;树状数组&plus;李超线段树)

    \(JUMP\) 很容易写出转移柿子 \[f_i=\min_{p_j<p_i}\{(h_i-h_j)^2+f_j\}+w_i\] 把\(\min\)里面的东西展开一下 \[f_j=\min_{p ...

  9. codeforces 70 D&period; Professor&&num;39&semi;s task 动态凸包

    地址:http://codeforces.com/problemset/problem/70/D 题目: D. Professor's task time limit per test 1 secon ...

随机推荐

  1. MongoDB 数组

    MongoDB是文档型数据库,每个文档(doc)表示数据的一项记录.相比关系型DB的row只能使用简单的数据类型,doc能够使用复杂的数据类型:内嵌doc,数组.MongoDB的数组是一系列元素的集合 ...

  2. 用字符串模拟两个大数相加——java实现

    问题: 大数相加不能直接使用基本的int类型,因为int可以表示的整数有限,不能满足大数的要求.可以使用字符串来表示大数,模拟大数相加的过程. 思路: 1.反转两个字符串,便于从低位到高位相加和最高位 ...

  3. &lbrack;转&rsqb;mysql 导入导出数据库以及函数、存储过程的介绍

    本篇文章是对mysql中的导入导出数据库命令以及函数.存储过程进行了详细的分析介绍,需要的朋友参考下: mysql常用导出数据命令:1.mysql导出整个数据库  mysqldump -hhostna ...

  4. SQL Server函数格式

    函数格式CREATE FUNCTION -- ============================================= -- Author: Clive Chinery -- Cre ...

  5. phpcms基础知识和配置

    一.设置界面 1.站点设置:相当于服务器上的站点 (1)站点修改:“关键词”和“描述”的修改,便于网络优化和搜索引擎对本网站的搜索. (2)模板的修改,可以自己加模板,引用自己模板 2.基本设置:所有 ...

  6. Maven学习(二)-- Maven项目构建过程练习

    摘自:http://www.cnblogs.com/xdp-gacl/p/4051690.html 一.创建Maven项目 1.1.建立Hello项目 1.首先建立Hello项目,同时建立Maven约 ...

  7. webrtc aecd算法解析一(原理分析)

    webrtc的回声抵消(aec.aecm)算法主要包括以下几个重要模块: 回声时延估计 NLMS(归一化最小均方自适应算法) NLP(非线性滤波) CNG(舒适噪声产生) 回声时延估计 这张图很多东西 ...

  8. jquery fullPage

    FROM : http://www.dowebok.com/77.html 应用: http://txhd.163.com/

  9. android中sharedPreferences的用法&lpar;转&rpar;

    SharedPreferences介绍:   做软件开发应该都知道,很多软件会有配置文件,里面存放这程序运行当中的各个属性值,由于其配置信息并不多,如果采用数据库来存放并不划算,因为数据库连接跟操作等 ...

  10. zoj4019 Schr&&num;246&semi;dinger&&num;39&semi;s Knapsack(dp)

    题意:有两种物品分别为n,m个,每种物品对应价值k1,k2.有一个容量为c的背包,每次将一个物品放入背包所获取的价值为k1/k2*放入物品后的剩余体积.求问所获取的最大价值. 整体来看,优先放入体积较 ...