結果
| 問題 |
No.386 貪欲な領主
|
| コンテスト | |
| ユーザー |
cutmdo
|
| 提出日時 | 2019-09-03 18:49:08 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 9,320 bytes |
| コンパイル時間 | 1,749 ms |
| コンパイル使用メモリ | 144,540 KB |
| 最終ジャッジ日時 | 2025-01-07 16:24:16 |
|
ジャッジサーバーID (参考情報) |
judge1 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 6 WA * 10 |
コンパイルメッセージ
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;
}
cutmdo