Codeforces Round #722 (Div. 2) C. Parsa‘s Humongous Tree(中位数定理)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #722 (Div. 2) C. Parsa‘s Humongous Tree(中位数定理)相关的知识,希望对你有一定的参考价值。
容易猜到每个节点要么取 l i l_i li要么取值 r i r_i ri最优
这样就定义 f [ i ] [ 0 / 1 ] f[i][0/1] f[i][0/1]节点 i i i取 l i / r i l_i/r_i li/ri时,子树内的最大总收益
这样暴力转移就好了…
关于证明
设根节点 1 1 1有 k k k个儿子,设最后构造的最优答案中权值从小到大分别为 x 1 , x 2 . . . . x k x_1,x_2....x_k x1,x2....xk
设根节点选择权值 w ∈ [ l 1 , r 1 ] w\\in[l_1,r_1] w∈[l1,r1]
设权值比 w w w小的有 k 1 k_1 k1个,权值比 w w w大的有 k 2 k_2 k2个
重新给根节点赋值为 w − 1 w-1 w−1(暂时不考虑 k 1 , k 2 k_1,k_2 k1,k2的变化)
那么当 i ∈ [ 1 , k 1 ] i\\in[1,k_1] i∈[1,k1]时, x i x_i xi造成的贡献减少一(若此处 k 1 k_1 k1变小,贡献减小的就更小了)
当 i ∈ [ k 1 + 1 , k ] i\\in[k_1+1,k] i∈[k1+1,k]时, x i x_i xi造成的贡献增加一(若此处 k 1 k_1 k1变小,贡献增大的就更大了)
所以权值取 x − 1 x-1 x−1比权值取 x x x多 k 2 − k 1 k_2-k_1 k2−k1
权值取 x + 1 x+1 x+1比权值取 x x x多 k 1 − k 2 k_1-k_2 k1−k2
显然 x + 1 x+1 x+1和 x − 1 x-1 x−1显然有一个更优
所以权值取 l 1 l_1 l1或者 r 1 r_1 r1一定比取中间某个权值更优
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
const int mod = 998244353;
vector<int>vec[maxn];
long long f[maxn][3];
int l[maxn],r[maxn],n,m;
void dfs(int u,int fa)
{
f[u][0] = f[u][1] = 0;
for( auto v:vec[u] )
{
if( v==fa ) continue;
dfs(v,u);
f[u][0] += max( f[v][0]+abs( l[v]-l[u] ),f[v][1]+abs( r[v]-l[u] ) );
f[u][1] += max( f[v][0]+abs( l[v]-r[u] ),f[v][1]+abs( r[v]-r[u] ) );
}
}
int main()
{
int t; cin >> t;
while( t-- )
{
cin >> n;
for(int i=1;i<=n;i++) cin >> l[i] >> r[i];
for(int i=1;i<n;i++)
{
int L,R; scanf("%d%d",&L,&R );
vec[L].push_back( R );
vec[R].push_back( L );
}
dfs(1,1);
cout << max( f[1][0],f[1][1] ) << endl;
for(int i=1;i<=n;i++) vec[i].clear();
}
}
以上是关于Codeforces Round #722 (Div. 2) C. Parsa‘s Humongous Tree(中位数定理)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #722 (Div. 2) 20210525
Codeforces Round #722 (Div. 2)Codeforces-1529 ABC
Codeforces Round #722 (Div. 2)Codeforces-1529 ABCD
Codeforces Round #722 (Div. 2)Codeforces-1529 ABCD