Title
CodeForces 1401 D. Maximum Distributed Treenode
Time Limit
2 secondsios
Memory Limit
256 megabytesc++
Problem Description
You are given a tree that consists of n n n nodes. You should label each of its n − 1 n-1 n−1 edges with an integer in such way that satisfies the following conditions:this
Let’s define f ( u , v ) f(u,v) f(u,v) as the sum of the numbers on the simple path from node u u u to node v v v. Also, let ∑ i = 1 n − 1 ∑ j = i + 1 n f ( i , j ) \sum\limits_{i=1}^{n-1} \sum\limits_{j=i+1}^n f(i,j) i=1∑n−1j=i+1∑nf(i,j) be a distribution index of the tree.spa
Find the maximum possible distribution index you can get. Since answer can be too large, print it modulo 1 0 9 + 7 10^9 + 7 109+7.code
In this problem, since the number k k k can be large, the result of the prime factorization of k k k is given instead.orm
Input
The first line contains one integer t t t ( 1 ≤ t ≤ 100 1 \le t \le 100 1≤t≤100) — the number of test cases.排序
The first line of each test case contains a single integer n n n ( 2 ≤ n ≤ 1 0 5 2 \le n \le 10^5 2≤n≤105) — the number of nodes in the tree.ip
Each of the next n − 1 n-1 n−1 lines describes an edge: the i i i-th line contains two integers u i u_i ui and v i v_i vi ( 1 ≤ u i , v i ≤ n 1 \le u_i, v_i \le n 1≤ui,vi≤n; u i ≠ v i u_i \ne v_i ui=vi) — indices of vertices connected by the i i i-th edge.ci
Next line contains a single integer m m m ( 1 ≤ m ≤ 6 ⋅ 1 0 4 1 \le m \le 6 \cdot 10^4 1≤m≤6⋅104) — the number of prime factors of k k k.
Next line contains m m m prime numbers p 1 , p 2 , … , p m p_1, p_2, \ldots, p_m p1,p2,…,pm ( 2 ≤ p i < 6 ⋅ 1 0 4 2 \le p_i < 6 \cdot 10^4 2≤pi<6⋅104) such that k = p 1 ⋅ p 2 ⋅ … ⋅ p m k = p_1 \cdot p_2 \cdot \ldots \cdot p_m k=p1⋅p2⋅…⋅pm.
It is guaranteed that the sum of n n n over all test cases doesn’t exceed 1 0 5 10^5 105, the sum of m m m over all test cases doesn’t exceed 6 ⋅ 1 0 4 6 \cdot 10^4 6⋅104, and the given edges for each test cases form a tree.
Output
Print the maximum distribution index you can get. Since answer can be too large, print it modulo 1 0 9 + 7 10^9+7 109+7.
Sample Input
3 4 1 2 2 3 3 4 2 2 2 4 3 4 1 3 3 2 2 3 2 7 6 1 2 3 4 6 7 3 5 1 3 6 4 7 5 13 3
Sample Onput
17 18 286
Note
In the first test case, one of the optimal ways is on the following image:
In this case, f ( 1 , 2 ) = 1 f(1,2)=1 f(1,2)=1, f ( 1 , 3 ) = 3 f(1,3)=3 f(1,3)=3, f ( 1 , 4 ) = 5 f(1,4)=5 f(1,4)=5, f ( 2 , 3 ) = 2 f(2,3)=2 f(2,3)=2, f ( 2 , 4 ) = 4 f(2,4)=4 f(2,4)=4, f ( 3 , 4 ) = 2 f(3,4)=2 f(3,4)=2, so the sum of these 6 6 6 numbers is 17 17 17.
In the second test case, one of the optimal ways is on the following image:
In this case, f ( 1 , 2 ) = 3 f(1,2)=3 f(1,2)=3, f ( 1 , 3 ) = 1 f(1,3)=1 f(1,3)=1, f ( 1 , 4 ) = 4 f(1,4)=4 f(1,4)=4, f ( 2 , 3 ) = 2 f(2,3)=2 f(2,3)=2, f ( 2 , 4 ) = 5 f(2,4)=5 f(2,4)=5, f ( 3 , 4 ) = 3 f(3,4)=3 f(3,4)=3, so the sum of these 6 6 6 numbers is 18 18 18.
Source
CodeForces 1401 D. Maximum Distributed Tree
題意
給一棵樹 你能夠任意分配邊權
但要使得全部邊權乘積 = = k ==k ==k
k是按質因子形式給出
設 f ( i , j ) f(i,j) f(i,j)是 i i i與 j j j路徑邊權和。
要使得全部點對邊權和 ∑ i = 1 n − 1 ∑ j = i + 1 n f ( i , j ) \sum\limits_{i=1}^{n-1} \sum\limits_{j=i+1}^n f(i,j) i=1∑n−1j=i+1∑nf(i,j)最大。
思路
經典全部點對邊權和,對每條邊來講貢獻就是左邊點的個數*右邊點的個數。
求出來排個序。
對於 k k k來講
若是他的質因子個數不足 n − 1 n-1 n−1則補 1 1 1便可
若是超過 n − 1 n-1 n−1呢?
則思考兩兩乘起來合併
是大的兩兩合併更優(粗略證實
設質因子爲 p 0 p 1 p 2 p0 p1 p2 p0p1p2
邊數貢獻爲 c 0 c 1 c0c1 c0c1
均從大到小排序
則 p 0 ∗ c 0 + p 1 ∗ c 0 + p 2 ∗ c 1 > p 0 ∗ c 0 + p 1 ∗ c 1 + p 2 ∗ c 1 p0*c0+p1*c0+p2*c1>p0*c0+p1*c1+p2*c1 p0∗c0+p1∗c0+p2∗c1>p0∗c0+p1∗c1+p2∗c1
則合併便可
最後對應相乘就是答案,別忘了取模 1 0 9 + 7 10^9+7 109+7
AC代碼:
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int, int> pii; typedef pair<ll, ll> pll; const int maxn = 3e5 + 5; const ll inf = 0x3f3f3f3f; const ll mod = 1e9 + 7; #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() void dfs(int now, int fa, vector<vector<int>> &edge, vector<ll> &c, vector<ll> &sz, int n) { sz[now] = 1; for (auto &it : edge[now]) { if (it == fa) continue; dfs(it, now, edge, c, sz, n); sz[now] += sz[it]; } c.emplace_back(sz[now] * (n - sz[now])); } int main() { ios::sync_with_stdio(false); cin.tie(0), cout.tie(0); int T; cin >> T; while (T--) { int n; cin >> n; vector<vector<int>> edge(n + 1, vector<int>()); for (int i = 1, u, v; i < n; ++i) { cin >> u >> v; edge[u].emplace_back(v); edge[v].emplace_back(u); } int m; cin >> m; deque<ll> dq(m); for (auto &it : dq) cin >> it; sort(all(dq), greater<ll>()); while (dq.size() > n - 1) { dq[1] = dq[0] * dq[1] % mod; dq.pop_front(); } while (dq.size() < n - 1) dq.push_back(1); vector<ll> c, sz(n + 1); dfs(1, 0, edge, c, sz, n); sort(all(c), greater<ll>()); ll ans = 0; for (int i = 0; i < n - 1; ++i) { ans = (ans + c[i] * dq[i] % mod) % mod; } cout << ans << endl; } return 0; }