ポータル
Luogu
問題解決のためのアイデア
これは木であるので、彼らは共同の重みを生成することができた場合の二点となるよう、そして、彼らは唯一の唯一の通過点で一致させることができるので、我々は通過点を列挙します。
しかし、我々は、各ポイントの周りのポイントはペアごとのマッチングを引き出す場合、複雑さが明らかに負担されていない、ということでしょう。
:数学的導出を考える
列の場合(\ {A_N \} \)\、ペアワイズ値の結果を合わせた重量として得一致:
\ [\ sum_ {IがJに<} 2a_ia_j = \ \ sum_(左^ {I = 1です。} {N} a_iを\右)^
2- \ sum_ {i = 1} ^ na_i ^ 2 \] 、これは、それが明らかであるはずですあなたは完全平方式はしないだろうしています
だから我々は、その後も限り2最大として選出された、非常に良い統計値と最大値をしている\(a_iを\)うまく一致します。
詳細注意事項
- このトピックで最大ピット:無剰余最大出力、および剰余への出力
参照コード
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= c == '-', c = getchar();
while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
s = f ? -s : s;
}
const int p = 10007;
const int _ = 200002;
int n, val[_];
int tot, head[_], nxt[_ << 1], ver[_ << 1];
inline void Add_edge(int u, int v)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v; }
int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
#endif
read(n);
for (rg int u, v, i = 1; i < n; ++i)
read(u), read(v), Add_edge(u, v), Add_edge(v, u);
for (rg int i = 1; i <= n; ++i) read(val[i]);
int ans1 = 0, ans2 = 0;
for (rg int u = 1; u <= n; ++u) {
int mx = 0, _mx = 0, sum1 = 0, sum2 = 0;
for (rg int i = head[u]; i; i = nxt[i]) {
int w = val[ver[i]];
if (w > mx) _mx = mx, mx = w;
else if (w > _mx) _mx = w;
sum1 = (sum1 + w) % p;
sum2 = (sum2 + 1ll * w * w % p) % p;
}
ans1 = max(ans1, mx * _mx);
ans2 = (ans2 + 1ll * sum1 * sum1 - sum2) % p;
}
printf("%d %d\n", ans1, ans2 % p);
return 0;
}
エンドSahua \(qwq \)