网站icp备案号,哪家网站建设公司好,网站建设入门教程视频,网站备案logo题意#xff1a;给一棵 nnn 个点的有点权的树#xff0c;你需要找 kkk 条根到叶子的路径#xff0c;使得路径并集的权值和最大。 n≤2105n\leq 2\times 10^5n≤2105
其实就是个贪心#xff0c;只是从这个角度更自然一点(
先有个显然的 dp#xff0c;设 f(u,k)f(u,k)f(u,…题意给一棵 nnn 个点的有点权的树你需要找 kkk 条根到叶子的路径使得路径并集的权值和最大。
n≤2×105n\leq 2\times 10^5n≤2×105
其实就是个贪心只是从这个角度更自然一点(
先有个显然的 dp设 f(u,k)f(u,k)f(u,k) 为从 uuu 往下找 kkk 条链覆盖的权值最大值。
f′(u,k)maxi0k{f(u,i)f(v,k−i)}[k0]auf(u,k)\max_{i0}^k \{f(u,i)f(v,k-i)\}[k0]a_uf′(u,k)i0maxk{f(u,i)f(v,k−i)}[k0]au
发现是个闵可夫斯基和的形式。
然后往这个方向考虑不管怎么理解都能看出这是个凸壳。
所以合并的时候继承叶子最多的儿子或者直接继承子树最大的也可以的凸包其他的暴力做闵可夫斯基和。可以用堆来维护斜率也就是差分然后暴力插入。最后把第一项 aua_uau 即可。
复杂度是 O(nlog2n)\Omicron(n\log ^2n)O(nlog2n)但常数很小。
脑抽写了个平衡树我是 SB
#include iostream
#include cstdio
#include cstring
#include cctype
#include vector
#include cstdlib
#define MAXN 200005
using namespace std;
inline int read()
{int ans0;char cgetchar();while (!isdigit(c)) cgetchar();while (isdigit(c)) ans(ans3)(ans1)(c^48),cgetchar();return ans;
}
typedef long long ll;
int ch[MAXN][2],key[MAXN],tot;
ll val[MAXN];
inline int newnode(int v){return val[tot]v,key[tot]rand(),tot;}
int merge(int x,int y)
{if (!x||!y) return x|y;if (key[x]key[y]) return ch[x][1]merge(ch[x][1],y),x;return ch[y][0]merge(x,ch[y][0]),y;
}
void split(int x,ll v,int l,int r)
{if (!x) return (void)(lr0);if (val[x]v) split(ch[x][1],v,l,r),ch[x][1]l,lx;else split(ch[x][0],v,l,r),ch[x][0]r,rx;
}
int getfir(int x)
{if (!ch[x][0]) {int tx;xch[x][1],ch[t][1]0;return t;}return getfir(ch[x][0]);
}
inline void insert(int x,int v)
{int l,r;split(x,val[v],l,r);xmerge(merge(l,v),r);
}
vectorint e[MAXN];
int a[MAXN],rt[MAXN],lev[MAXN],son[MAXN];
void dfs(int u)
{if (e[u].empty()) return (void)(lev[u]1);for (int i0;i(int)e[u].size();i){dfs(e[u][i]);if (lev[e[u][i]]lev[son[u]]) son[u]e[u][i];lev[u]lev[e[u][i]];}
}
void Dfs(int u)
{if (son[u]) Dfs(son[u]),rt[u]rt[son[u]];else return (void)(rt[u]newnode(a[u]));for (int i0;i(int)e[u].size();i)if (e[u][i]!son[u]){Dfs(e[u][i]);while (rt[e[u][i]]) insert(rt[u],getfir(rt[e[u][i]]));}int pgetfir(rt[u]);val[p]a[u];rt[u]merge(p,rt[u]);
}
int main()
{int n,k;nread(),kread();for (int i1;in;i) a[i]read();for (int i1;in;i){int u,v;uread(),vread();e[u].push_back(v);}dfs(1),Dfs(1);ll ans0;while (k--) ansval[getfir(rt[1])];coutans;return 0;
}