제출 #1156949

#제출 시각아이디문제언어결과실행 시간메모리
1156949SmuggingSpunMagic Tree (CEOI19_magictree)C++20
20 / 100
1036 ms175320 KiB
#include<bits/stdc++.h> #define taskname "B" using namespace std; typedef long long ll; template<class T>void maximize(T& a, T b){ if(a < b){ a = b; } } const int lim = 1e5 + 5; int n, m, k, parent[lim], vertex[lim], day[lim], weight[lim]; vector<int>g[lim]; namespace sub1{ void solve(){ vector<int>low(n + 1), tail(n + 1); int euler = -1; auto dfs = [&] (auto&& self, int s) -> void{ low[s] = ++euler; for(int& d : g[s]){ self(self, d); } tail[s] = euler; }; dfs(dfs, 1); vector<pair<int, int>>fruit(n, make_pair(-1, 0)); for(int i = 1; i <= m; i++){ fruit[low[vertex[i]]] = make_pair(day[i] - 1, weight[i]); } vector<vector<ll>>f(k, vector<ll>(1 << n, -1)); auto dp = [&] (auto&& self, int p, int mask) -> ll{ if(p == k){ return 0; } ll& ans = f[p][mask]; if(ans != -1){ return ans; } ans = self(self, p + 1, mask); for(int i = 2; i <= n; i++){ if(1 << low[i] & mask){ int nxt = mask; ll add = 0; for(int j = low[i]; j <= tail[i]; j++){ if(1 << j & nxt){ nxt ^= 1 << j; if(fruit[j].first == p){ add += fruit[j].second; } } } maximize(ans, self(self, p, nxt) + add); } } return ans; }; cout << dp(dp, 0, (1 << n) - 1); } } namespace sub2{ void solve(){ cout << accumulate(weight + 1, weight + m + 1, 0LL); } } namespace sub3{ void solve(){ vector<ll>bit(k + 1, 0); auto update = [&] (int p, ll x){ for(; p <= k; p += p & -p){ maximize(bit[p], x); } }; auto get = [&] (int p){ ll ans = 0; for(; p > 0; p -= p & -p){ maximize(ans, bit[p]); } return ans; }; vector<pair<int, int>>fruit(n + 1, make_pair(-1, 0)); for(int i = 1; i <= m; i++){ fruit[vertex[i]] = make_pair(day[i], weight[i]); } for(int i = n; i > 1; i--){ if(fruit[i].first != -1){ update(fruit[i].first, get(fruit[i].first) + fruit[i].second); } } cout << get(k); } } namespace sub45{ void solve(){ vector<vector<ll>>dp(n + 1, vector<ll>(k + 1, 0)); vector<pair<int, int>>fruit(n + 1, make_pair(k, 0)); for(int i = 1; i <= m; i++){ fruit[vertex[i]] = make_pair(day[i], weight[i]); } auto dfs = [&] (auto&& self, int s) -> void{ for(int& d : g[s]){ self(self, d); } for(int i = 1; i <= k; i++){ ll sum = 0; for(int& d : g[i]){ sum += dp[d][i]; } dp[s][i] = max(dp[s][i - 1], sum + (fruit[i].first == i ? fruit[i].second : 0)); } }; dfs(dfs, 1); cout << dp[1][k]; } } int main(){ ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0); if(fopen(taskname".inp", "r")){ freopen(taskname".inp", "r", stdin); } cin >> n >> m >> k; bool is_sub2 = true, is_sub3 = true; for(int i = 2; i <= n; i++){ cin >> parent[i]; if(parent[i] != i - 1){ is_sub3 = false; } g[parent[i]].emplace_back(i); } for(int i = 1; i <= m; i++){ cin >> vertex[i] >> day[i] >> weight[i]; if(!g[vertex[i]].empty()){ is_sub2 = false; } } if(max(n, k) <= 20){ sub1::solve(); } else if(is_sub2){ sub2::solve(); } else if(is_sub3){ sub3::solve(); } else if(k <= 20){ sub45::solve(); } }

컴파일 시 표준 에러 (stderr) 메시지

magictree.cpp: In function 'int main()':
magictree.cpp:117:24: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  117 |                 freopen(taskname".inp", "r", stdin);
      |                 ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...