QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#335886 | #7415. Fast Spanning Tree | hos_lyric | WA | 31ms | 201668kb | C++14 | 7.4kb | 2024-02-24 08:39:35 | 2024-02-24 08:39:36 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
// Meldable
// 0 for null, ts[0] = T()
// chPoint(u, a): point update
// chRange(u, a, b): range update s.t. T() -> T()
// T::push(T *l, T *r)
// T::pull(const T &l, const T &r)
// T::meld(const T &t)
template <class T> struct Seg {
static constexpr int NUM_NODES = 1 << 23;
int l0, r0;
int nodesLen;
int ls[NUM_NODES], rs[NUM_NODES];
T ts[NUM_NODES];
void init(int l0_, int r0_) {
l0 = l0_;
r0 = r0_;
nodesLen = 1;
ls[0] = rs[0] = 0;
ts[0] = T();
}
int newNode() {
assert(nodesLen < NUM_NODES);
const int u = nodesLen++;
ls[u] = rs[u] = 0;
ts[u] = T();
return u;
}
void push(int u) {
ts[u].push(ls[u] ? &ts[ls[u]] : nullptr, rs[u] ? &ts[rs[u]] : nullptr);
}
void pull(int u) {
ts[u].pull(ts[ls[u]], ts[rs[u]]);
}
template <class F, class... Args>
void chPoint(int &u, int l, int r, int a, F f, Args &&... args) {
if (!u) u = newNode();
if (l + 1 == r) {
(ts[u].*f)(args...);
return;
}
const int mid = l + ((r - l) >> 1);
push(u);
(a < mid)
? chPoint(ls[u], l, mid, a, f, args...)
: chPoint(rs[u], mid, r, a, f, args...);
pull(u);
}
template <class F, class... Args>
void chPoint(int &u, int a, F f, Args &&... args) {
assert(l0 <= a); assert(a < r0);
chPoint(u, l0, r0, a, f, args...);
}
template <class F, class... Args>
void chRange(int &u, int l, int r, int a, int b, F f, Args &&... args) {
if (!u) return;
if (b <= l || r <= a) return;
if (a <= l && r <= b) {
(ts[u].*f)(args...);
return;
}
const int mid = l + ((r - l) >> 1);
push(u);
chRange(ls[u], l, mid, a, b, f, args...);
chRange(rs[u], mid, r, a, b, f, args...);
pull(u);
}
template <class F, class... Args>
void chRange(int &u, int a, int b, F f, Args &&... args) {
assert(l0 <= a); assert(a <= b); assert(b <= r0);
chRange(u, l0, r0, a, b, f, args...);
}
T get(int u, int l, int r, int a, int b) {
if (!u) return T();
if (b <= l || r <= a) return T();
if (a <= l && r <= b) return ts[u];
const int mid = l + ((r - l) >> 1);
push(u);
const T tL = get(ls[u], l, mid, a, b);
const T tR = get(rs[u], mid, r, a, b);
pull(u);
T t;
t.pull(tL, tR);
return t;
}
T get(int u, int a, int b) {
assert(l0 <= a); assert(a <= b); assert(b <= r0);
return get(u, l0, r0, a, b);
}
// Frees v.
int meld(int u, int v, int l, int r) {
if (!u) return v;
if (!v) return u;
if (l + 1 == r) {
ts[u].meld(ts[v]);
return u;
}
const int mid = l + ((r - l) >> 1);
push(u);
push(v);
ls[u] = meld(ls[u], ls[v], l, mid);
rs[u] = meld(rs[u], rs[v], mid, r);
pull(u);
return u;
}
int meld(int u, int v) {
return meld(u, v, l0, r0);
}
/*
void print(int depth, int u, int l, int r) const {
if (!u) return;
cerr << string(2 * depth, ' ') << u << " [" << l << ", " << r << ") " << ts[u] << endl;
if (l + 1 == r) return;
const int mid = l + ((r - l) >> 1);
print(depth + 1, ls[u], l, mid);
print(depth + 1, rs[u], mid, r);
}
void print(int u) const {
if (!u) cerr << "[Seg::print] null" << endl;
print(0, u, l0, r0);
}
//*/
};
constexpr Int INF = 1001001001001001001LL;
struct Node {
pair<Int, int> mn;
Int lz;
Node() : mn(INF, -1), lz(0) {}
void push(Node *l, Node *r) {
if (lz) {
if (l) l->add(lz);
if (r) r->add(lz);
lz = 0;
}
}
void pull(const Node &l, const Node &r) {
mn = min(l.mn, r.mn);
}
void meld(const Node &t) {
chmin(mn, t.mn);
}
void add(Int val) {
mn.first += val;
lz = 0;
}
// leaf
void change(Int val, int id) {
mn = make_pair(val, id);
}
};
vector<int> uf;
int root(int u) {
return (uf[u] < 0) ? u : (uf[u] = root(uf[u]));
}
bool connect(int u, int v) {
u = root(u);
v = root(v);
if (u == v) return false;
if (uf[u] > uf[v]) swap(u, v);
uf[u] += uf[v];
uf[v] = u;
return true;
}
Seg<Node> seg;
int N, M;
vector<Int> W;
vector<int> A, B;
vector<Int> S;
int main() {
for (; ~scanf("%d%d", &N, &M); ) {
W.resize(N);
for (int u = 0; u < N; ++u) {
scanf("%lld", &W[u]);
}
A.resize(M);
B.resize(M);
S.resize(M);
for (int i = 0; i < M; ++i) {
scanf("%d%d%lld", &A[i], &B[i], &S[i]);
--A[i];
--B[i];
}
uf.assign(N, -1);
vector<Int> ws = W;
seg.init(0, M << 1);
vector<int> fs(N, 0);
for (int u = 0; u < N; ++u) {
fs[u] = seg.newNode();
}
priority_queue<int, vector<int>, greater<int>> que;
auto update = [&](int i) -> void {
// cerr<<"[update] i = "<<i<<endl;
const int ra = root(A[i]);
const int rb = root(B[i]);
const Int hp = S[i] - ws[ra] - ws[rb];
if (hp <= 0) {
que.push(i);
seg.chPoint(fs[ra], i << 1 | 0, &Node::change, INF, -1);
seg.chPoint(fs[rb], i << 1 | 1, &Node::change, INF, -1);
} else {
seg.chPoint(fs[ra], i << 1 | 0, &Node::change, (hp - 1) / 2, i);
seg.chPoint(fs[rb], i << 1 | 1, &Node::change, (hp ) / 2, i);
}
};
for (int i = 0; i < M; ++i) {
update(i);
}
vector<int> ans;
for (; que.size(); ) {
const int i = que.top();
que.pop();
const int ra = root(A[i]);
const int rb = root(B[i]);
// cerr<<"merge? "<<i<<" "<<ra<<" "<<rb<<endl;
if (ra != rb) {
ans.push_back(i);
seg.chRange(fs[ra], 0, M << 1, &Node::add, ws[rb]);
seg.chRange(fs[rb], 0, M << 1, &Node::add, ws[ra]);
connect(ra, rb);
const int r = root(ra);
ws[r] = ws[ra] + ws[rb];
fs[r] = seg.meld(fs[ra], fs[rb]);
for (; seg.ts[fs[r]].mn.first <= 0; ) {
// cerr<<" mn = "<<seg.ts[fs[r]].mn<<endl;
update(seg.ts[fs[r]].mn.second);
}
}
}
printf("%d\n", (int)ans.size());
for (int j = 0; j < (int)ans.size(); ++j) {
if (j) printf(" ");
printf("%d", ans[j] + 1);
}
puts("");
}
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 24ms
memory: 201024kb
input:
5 5 1 4 3 4 0 4 5 5 3 1 1 2 5 2 4 3 1 4 1 4
output:
4 2 3 1 4
result:
ok 5 number(s): "4 2 3 1 4"
Test #2:
score: 0
Accepted
time: 28ms
memory: 201668kb
input:
3 5 3 2 2 1 2 6 1 2 6 1 2 3 1 2 6 2 3 6
output:
2 3 5
result:
ok 3 number(s): "2 3 5"
Test #3:
score: 0
Accepted
time: 27ms
memory: 201180kb
input:
10 20 4 6 6 1 7 9 1 8 7 9 5 3 2 1 10 10 5 6 7 9 6 9 3 1 1 6 8 1 5 7 0 9 5 4 10 3 4 8 6 8 3 10 6 5 3 8 3 7 9 1 9 10 10 1 0 5 7 6 6 10 1 6 5 9 5 8 2 9 2 4
output:
8 1 2 3 4 5 6 7 20
result:
ok 9 numbers
Test #4:
score: -100
Wrong Answer
time: 31ms
memory: 201572kb
input:
10 20 0 10 4 6 2 0 2 0 2 8 5 10 8 7 1 6 10 5 0 9 8 0 5 8 4 5 1 8 10 3 6 5 4 3 9 2 6 10 3 6 4 3 1 3 10 3 6 1 3 3 2 5 6 9 2 4 2 5 10 6 5 8 6 3 2 1 0 2 3 6
output:
8 1 4 5 7 8 9 15 19
result:
wrong answer 1st numbers differ - expected: '9', found: '8'