結果
問題 | No.386 貪欲な領主 |
ユーザー | cutmdo |
提出日時 | 2019-09-03 18:49:08 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 9,320 bytes |
コンパイル時間 | 1,783 ms |
コンパイル使用メモリ | 150,824 KB |
実行使用メモリ | 45,880 KB |
最終ジャッジ日時 | 2024-06-06 18:20:12 |
合計ジャッジ時間 | 5,542 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,812 KB |
testcase_01 | AC | 2 ms
6,944 KB |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | AC | 209 ms
45,756 KB |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | AC | 2 ms
6,940 KB |
testcase_11 | AC | 2 ms
6,944 KB |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | AC | 187 ms
45,880 KB |
コンパイルメッセージ
main.cpp: In static member function 'static auto HLDecomposition::getRoot(ll, const std::unordered_multimap<long long int, long long int>&)': main.cpp:187:9: warning: control reaches end of non-void function [-Wreturn-type] 187 | } | ^
ソースコード
#include <iostream> #include <iomanip> #include <string> #include <cmath> #include <algorithm> #include <vector> #include <set> #include <map> #include <unordered_map> #include <unordered_set> #include <list> #include <stack> #include <queue> #include <bitset> #include <numeric> #include <cassert> #ifdef DEBUG #include "./Lib/debug.hpp" #else #define dump(...) template<class T>inline auto d_val(T a, T b) { return a; } #endif /* (=^o^=) */ #define int ll /* macro */ #define FOR(i, b, e) for(ll i = (ll)(b); i < (ll)(e); ++i) #define RFOR(i, b, e) for(ll i = (ll)(e-1); i >= (ll)(b); --i) #define REP(i, n) FOR(i, 0, n) #define RREP(i, n) RFOR(i, 0, n) #define REPC(x,c) for(const auto& x:(c)) #define REPI2(it,b,e) for(auto it = (b); it != (e); ++it) #define REPI(it,c) REPI2(it, (c).begin(), (c).end()) #define RREPI(it,c) REPI2(it, (c).rbegin(), (c).rend()) #define REPI_ERACE2(it, b, e) for(auto it = (b); it != (e);) #define REPI_ERACE(it, c) REPI_ERACE2(it, (c).begin(), (c).end()) #define ALL(x) (x).begin(),(x).end() #define cauto const auto& /* macro func */ #define SORT(x) do{sort(ALL(x));}while(false) #define RSORT(x) do{sort((x).rbegin(),(x).rend());}while(false) #define UNIQUE(v) do{v.erase( unique(v.begin(), v.end()), v.end() );}while(false) #define MAX(x,y) do{x = std::max(x,y);}while(false) #define MIN(x,y) do{x = std::min(x,y);}while(false) #define BR do{cout<<"\n";}while(false) /* type define */ using ll = long long; using PAIR = std::pair<ll, ll>; using VS = std::vector<std::string>; using VL = std::vector<long long>; using VVL = std::vector<VL>; using VVVL = std::vector<VVL>; using VD = std::vector<double>; template<class T> using V = std::vector<T>; /* using std */ using std::cout; constexpr char endl = '\n'; using std::cin; using std::sort; using std::pair; using std::string; using std::stack; using std::queue; using std::vector; using std::list; using std::map; using std::unordered_map; using std::multimap; using std::unordered_multimap; using std::set; using std::unordered_set; using std::unordered_multiset; using std::multiset; using std::bitset; using std::priority_queue; /* constant value */ constexpr ll MOD = 1000000007; //constexpr ll MOD = 998244353; /* Initial processing */ struct Preprocessing { Preprocessing() { std::cin.tie(0); std::ios::sync_with_stdio(0); }; }_Preprocessing; /* Remove the source of the bug */ signed pow(signed, signed) { assert(false); return -1; } /* define hash */ namespace std { template <> class hash<std::pair<ll, ll>> { public: size_t operator()(const std::pair<ll, ll>& x) const { return hash<ll>()(1000000000 * x.first + x.second); } }; } /* input */ template<class T> std::istream& operator >> (std::istream& is, vector<T>& vec) { for (T& x : vec) is >> x; return is; } //============================================================================================= /** * セグメント木を構成する * 2methodの変更により調整 */ template<class T> class SegmentTree { private: const T initialValue = 0; const T ignoreValue = 0; const ll m_size; vector<T> m_node; ll calcSize(ll n) { ll size = 1; while (size < n) { size *= 2; } return size; } /** * 値の更新(更新:=, 加算:+=, etc...) */ void update(ll k, T x) { m_node[k] = x; } /** * 値の併合 */ T merge(T xl, T xr) { return xl + xr; } public: SegmentTree(ll n) : m_size(calcSize(n)), m_node(m_size * 2 - 1, initialValue) {} void add(ll itr, T val) { ll i = itr + m_size - 1; update(i, val); while (i > 0) { i = (i - 1) / 2; m_node[i] = merge(m_node[i * 2 + 1], m_node[i * 2 + 2]); } /** cout << "-- tree -- " << endl; REP(i, 2 * m_size - 1) { cout << m_node[i] << endl; } /*//**/ } T query(ll a, ll b) { return query(a, b + 1, 0, 0, m_size); } T query(ll a, ll b, ll k, ll l, ll r) { if (r <= a || b <= l) { return ignoreValue; } if (a <= l && r <= b) { return m_node[k]; } return merge( query(a, b, 2 * k + 1, l, (l + r) / 2), query(a, b, 2 * k + 2, (l + r) / 2, r) ); } }; class HLDecomposition { std::unordered_multimap<int, int> m_graph; std::unordered_map<int, int> m_graphRev; const int m_root; std::vector<int> m_nodeList; std::vector<int> m_nodeListPos; std::vector<int> m_nodeCostList; std::vector<std::pair<int, int>> m_nodeRange; SegmentTree<int> m_tree; static auto reverse(const std::unordered_multimap<int, int>& graph) { std::unordered_map<int, int> graphRev; for (const auto& p : graph) { graphRev.emplace(p.second, p.first); } return graphRev; } static auto getRoot(int size, const unordered_multimap<int, int>& graph) { std::vector<bool> children(size, false); for (const auto& p : graph) { children[p.second] = true; } for (int i = 0; i < size; ++i)if (!children[i]) { return i; } } static auto getTreeSize(int size, const unordered_multimap<int, int>& graph, int root) { auto treeSize = std::vector<int>(size, 1); auto calcTreeSize = [&](auto f, auto from) { auto range = graph.equal_range(from); if (range.first == range.second) { return; } for (auto itr = range.first; itr != range.second; ++itr) { auto to = itr->second; f(f, to); treeSize[from] += treeSize[to]; } }; calcTreeSize(calcTreeSize, root); return treeSize; } auto decomposition(const unordered_multimap<int, int>& graph, const std::vector<int>& nodeCost, const std::vector<int>& tSize, int now, int&& nodeFrom) { if (nodeFrom == -1) { nodeFrom = now; } m_nodeList.emplace_back(now); m_nodeCostList.emplace_back(nodeCost[now]); m_nodeListPos[now] = m_nodeList.size() - 1; m_nodeRange.emplace_back(m_nodeListPos[nodeFrom], -1); auto range = graph.equal_range(now); if (range.first == range.second) { for (int f = m_nodeListPos[nodeFrom]; f <= m_nodeListPos[now]; ++f) { m_nodeRange[f].second = m_nodeListPos[now]; } nodeFrom = -1; return; } auto large = -1; auto sMax = -1; for (auto itr = range.first; itr != range.second; ++itr) { auto to = itr->second; if (tSize[to] > sMax) { sMax = tSize[to]; large = to; } } decomposition(graph, nodeCost, tSize, large, std::forward<int>(nodeFrom)); for (auto itr = range.first; itr != range.second; ++itr) { auto to = itr->second; if (to == large) { continue; } decomposition(graph, nodeCost, tSize, to, std::forward<int>(nodeFrom)); } } auto construct(int size, const unordered_multimap<int, int>& graph, const std::vector<int>& nodeCost) { m_nodeList.reserve(size); m_nodeCostList.reserve(size); m_nodeRange.reserve(size); decomposition(graph, nodeCost, getTreeSize(size, graph, m_root), m_root, -1); } public: HLDecomposition(int size, const unordered_multimap<ll, ll>& graph, const std::vector<int>& nodeCost) : m_graph(graph), m_graphRev(reverse(m_graph)), m_root(getRoot(size, graph)), m_nodeListPos(size), m_tree(size) { construct(size, graph, nodeCost); for (int i = 0; i < size; ++i) { m_tree.add(i, m_nodeCostList[i]); } } HLDecomposition(int size, const unordered_multimap<int, int>& graph) : m_graph(graph), m_graphRev(reverse(m_graph)), m_root(getRoot(size, graph)), m_nodeListPos(size), m_tree(size) { construct(size, graph, std::vector<int>(size)); for (int i = 0; i < size; ++i) { m_tree.add(i, m_nodeCostList[i]); } } void debugOutput() const { dump(m_nodeList, m_nodeCostList, m_nodeRange); } /** * 最小共通祖先,LCA(Lowest Common Ancestor)を得る */ auto LCA(int a, int b) { while (a != b) { auto posa = m_nodeListPos[a]; auto posb = m_nodeListPos[b]; if (posa > posb) { std::swap(posa, posb); a = m_nodeList[posa]; } if (m_nodeRange[posb].first <= posa && posa <= m_nodeRange[posb].second) { b = a; break; } b = m_graphRev[m_nodeList[m_nodeRange[posb].first]]; } return a; } /** * セグ木を更新 *//**/ auto add(int itr, int x) { m_tree.add(itr, x); }/*/**/ /** * (遅延)セグ木から値を取得 */ auto query(int a, int b) { ll val = 0;//TODO: bool flg = false; while (a != b) { auto posa = m_nodeListPos[a]; auto posb = m_nodeListPos[b]; if (posa > posb) { std::swap(posa, posb); a = m_nodeList[posa]; } if (m_nodeRange[posb].first <= posa && posa <= m_nodeRange[posb].second) { val += m_tree.query(posa, posb); flg = true; b = a; break; } auto t = m_nodeRange[posb].first; val += m_tree.query(m_nodeRange[posb].first, posb); b = m_graphRev[m_nodeList[m_nodeRange[posb].first]]; } if (!flg) { val += m_tree.query(a, a); } return val; } }; signed main() { ll n; cin >> n; unordered_multimap<ll, ll> graph_; REP(_, n - 1) { ll a, b; cin >> a >> b; graph_.emplace(a, b); graph_.emplace(b, a); } unordered_multimap<ll, ll> graph; { V<bool> use(n); queue<ll> q; q.emplace(0); use[0] = true; while (!q.empty()) { ll from = q.front(); q.pop(); auto range = graph_.equal_range(from); REPI2(itr, range.first, range.second) { ll to = itr->second; if (!use[to]) { q.emplace(to); use[to] = true; graph.emplace(from, to); } } } } VL cost(n); cin >> cost; auto tree = HLDecomposition(n, graph, cost); ll q; cin >> q; ll ans = 0; REP(_, q) { ll a, b, c; cin >> a >> b >> c; ans += tree.query(a, b) * c; } cout << ans << endl; }