牛客国庆集训派对Day3 Solution
A Knight
留坑。
B Tree
思路:两次树形DP,但是要考虑0没有逆元
可以用前缀后缀做
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1000010 5 #define ll long long 6 7 const ll MOD = (ll)1e9 + 7; 8 9 10 int n; 11 ll dp[N], dp2[N]; 12 ll prefix[N], suffix[N]; 13 vector <int> G[N]; 14 15 void Init() 16 { 17 for (int i = 1; i <= n; ++i) dp[i] = 1, dp2[i] = 0, G[i].clear(); 18 } 19 20 void DFS(int u, int fa) 21 { 22 for (auto v : G[u]) 23 { 24 if (v == fa) continue; 25 DFS(v, u); 26 dp[u] = dp[u] * (dp[v] + 1) % MOD; 27 } 28 } 29 30 void DFS2(int u, int fa) 31 { 32 prefix[0] = 1; 33 suffix[G[u].size() + 1] = 1; 34 int len = G[u].size(); 35 for (int i = 0; i < len; ++i) 36 { 37 int v = G[u][i]; 38 if (v == fa) prefix[i + 1] = prefix[i]; 39 else prefix[i + 1] = prefix[i] * (dp[G[u][i]] + 1) % MOD; 40 } 41 for (int i = len - 1; i >= 0; --i) 42 { 43 int v = G[u][i]; 44 if (v == fa) suffix[i + 1] = suffix[i + 2]; 45 else suffix[i + 1] = suffix[i + 2] * (dp[G[u][i]] + 1) % MOD; 46 47 } 48 for (int i = 0; i < len; ++i) 49 { 50 int v = G[u][i]; 51 if (v == fa) continue; 52 dp2[v] = prefix[i] % MOD * suffix[i + 2] % MOD * (dp2[u] + 1) % MOD; 53 } 54 for (auto v : G[u]) 55 { 56 if (v == fa) continue; 57 DFS2(v, u); 58 } 59 } 60 61 void Run() 62 { 63 while (scanf("%d", &n) != EOF) 64 { 65 Init(); 66 for (int i = 1, u, v; i < n; ++i) 67 { 68 scanf("%d%d", &u, &v); 69 G[u].push_back(v); 70 G[v].push_back(u); 71 } 72 DFS(1, 0); DFS2(1, 0); 73 for (int i = 1; i <= n; ++i) printf("%lld ", dp[i] * (dp2[i] + 1) % MOD); 74 } 75 } 76 77 int main() 78 { 79 #ifdef LOCAL 80 freopen("Test.in", "r", stdin); 81 #endif 82 83 Run(); 84 return 0; 85 }
C Two Graphs
留坑。
D Shopping
贪心即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1010 5 6 int t, n, m; 7 int arr[N], res; 8 9 int main() 10 { 11 scanf("%d", &t); 12 while (t--) 13 { 14 res = 0; 15 scanf("%d%d", &n, &m); 16 for (int i = 1, b; i <= n; ++i) 17 { 18 scanf("%d%d", arr + i, &b); 19 if (b) ++res; 20 } 21 sort(arr + 1, arr + 1 + n); 22 res = min(res, m); 23 double ans = 0; 24 for (int i = n; i >= 1; --i, --res) 25 ans += res > 0 ? arr[i] * 1.0 / 2 : arr[i]; 26 printf("%.1f ", ans); 27 } 28 return 0; 29 }