QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#29454#2543. Edges, Colors and MSTsinbad#WA 2ms8364kbC++8.2kb2022-04-17 21:11:372022-04-28 15:04:52

Judging History

你现在查看的是最新测评结果

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2022-04-28 15:04:52]
  • 评测
  • 测评结果:WA
  • 用时:2ms
  • 内存:8364kb
  • [2022-04-17 21:11:37]
  • 提交

answer

// #define LOCAL
#define _USE_MATH_DEFINES
#include <array>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <complex>
#include <cmath>
#include <numeric>
#include <bitset>
#include <functional>
#include <random>
#include <ctime>

using namespace std;

template <typename A, typename B>
ostream& operator <<(ostream& out, const pair<A, B>& a) {
  out << "(" << a.first << "," << a.second << ")";
  return out;
}
template <typename T, size_t N>
ostream& operator <<(ostream& out, const array<T, N>& a) {
  out << "["; bool first = true;
  for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "]";
  return out;
}
template <typename T>
ostream& operator <<(ostream& out, const vector<T>& a) {
  out << "["; bool first = true;
  for (auto v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "]";
  return out;
}
template <typename T, class Cmp>
ostream& operator <<(ostream& out, const set<T, Cmp>& a) {
  out << "{"; bool first = true;
  for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "}";
  return out;
}
template <typename T, class Cmp>
ostream& operator <<(ostream& out, const multiset<T, Cmp>& a) {
  out << "{"; bool first = true;
  for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "}";
  return out;
}
template <typename U, typename T, class Cmp>
ostream& operator <<(ostream& out, const map<U, T, Cmp>& a) {
  out << "{"; bool first = true;
  for (auto& p : a) { out << (first ? "" : ", "); out << p.first << ":" << p.second; first = 0;} out << "}";
  return out;
}
#ifdef LOCAL
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
#else
#define trace(...) 42
#endif
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}

template <class T> auto vect(const T& v, int n) { return vector<T>(n, v); }
template <class T, class... D> auto vect(const T& v, int n, D... m) {
  return vector<decltype(vect(v, m...))>(n, vect(v, m...));
}

using int64 = long long;
using int128 = __int128_t;
using ii = pair<int, int>;
#define SZ(x) (int)((x).size())
template <typename T> static constexpr T inf = numeric_limits<T>::max() / 2;
const int MOD = 1e9 + 7;
// const int MOD = 998244353;
// mt19937 mrand(random_device{}());
// int rnd(int x) { return mrand() % x; }
mt19937_64 mrand(random_device{}());
int64 rnd(int64 x) { return mrand() % x; }
int lg2(int64 x) { return sizeof(int64) * 8 - 1 - __builtin_clzll(x); }
template <class T> void out(const vector<T>& a) { for (int i = 0; i < SZ(a); ++i) cout << a[i] << " \n"[i + 1 == SZ(a)]; }
template <class T> bool ckmin(T& a, const T& b) { return b < a ? a = b, 1 : 0; }
template <class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; }
template <class T> void dedup(vector<T>& v) { sort(v.begin(), v.end()); v.erase(unique(v.begin(), v.end()), v.end()); }
void add_mod(int& x, int y) { x += y; if (x >= MOD) x -= MOD; }
void sub_mod(int& x, int y) { x += MOD - y; if (x >= MOD) x -= MOD; }

struct fast_ios {
  fast_ios() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
  };
} fast_ios_;

const int N = 2e5 + 10;

vector<ii> a[N];
int t[N];
int son[N], f[N], dep[N], tin[N], sz[N], top[N], up[N];

void DFS(int u, int parent) {
  f[u] = parent;
  dep[u] = f[u] < 0 ? 0 : dep[f[u]] + 1;
  sz[u] = 1;
  son[u] = -1;
  for (auto& [v, k] : a[u]) {
    if (v == f[u]) continue;
    DFS(v, u);
    up[u] = k;
    sz[u] += sz[v];
    if (son[u] < 0 || sz[son[u]] < sz[v]) {
      son[u] = v;
    }
  }
}

int stamp;
void DFS2(int u, bool heavy) {
  tin[u] = stamp++;
  top[u] = heavy ? top[f[u]] : u;
  if (son[u] >= 0) DFS2(son[u], true);
  for (auto& [v, k] : a[u]) {
    if (v == f[u] || v == son[u]) continue;
    DFS2(v, false);
  }
}

struct Node {
  Node *left, *right;
  int64 sum, delta;
  int64 mn;
  void update(int a, int b, int64 c, int64 bound) {
    ckmin(mn, bound);
    sum = (b - a) * c;
    delta = c;
  }
  void pushup() {
    sum = left->sum + right->sum;
  }
  void pushdown(int a, int b) {
    if (delta) {
      int mid = (a + b) / 2;
      left->update(a, mid, delta, mn);
      right->update(mid, b, delta, mn);
      delta = 0;
    }
  }
};
Node pool[N << 1], *last;
Node* build(int a, int b) {
  Node* ret = last++;
  ret->sum = ret->delta = 0;
  ret->mn = inf<int64>;
  if (a + 1 == b) return ret;
  int mid = (a + b) / 2;
  ret->left = build(a, mid);
  ret->right = build(mid, b);
  return ret;
}
void insert(Node* cur, int a, int b, int ll, int rr, int64 c) {
  if (ll >= rr || a >= rr || b <= ll) return;
  if (a >= ll && b <= rr) {
    cur->update(a, b, 1, c);
    return;
  }
  cur->pushdown(a, b);
  int mid = (a + b) / 2;
  insert(cur->left, a, mid, ll, rr, c);
  insert(cur->right, mid, b, ll, rr, c);
  cur->pushup();
}
int64 query(Node* cur, int a, int b, int ll, int rr) {
  if (ll >= rr || a >= rr || b <= ll) return 0LL;
  if (a >= ll && b <= rr) {
    return cur->sum;
  }
  cur->pushdown(a, b);
  int mid = (a + b) / 2;
  int64 ret = 0;
  ret += query(cur->left, a, mid, ll, rr);
  ret += query(cur->right, mid, b, ll, rr);
  return ret;
}
int64 query2(Node* cur, int a, int b, int pos) {
  if (pos < a || pos >= b) return inf<int64>;
  if (a + 1 == b) return cur->mn;
  cur->pushdown(a, b);
  int mid = (a + b) / 2;
  int64 ret = inf<int64>;
  ckmin(ret, query2(cur->left, a, mid, pos));
  ckmin(ret, query2(cur->right, mid, b, pos));
  return ret;
}


int main() {
  int n, m;
  cin >> n >> m;
  vector<array<int, 3>> e(m);
  for (int i = 0; i < m; ++i) {
    int x, y, k;
    cin >> x >> y >> k;
    --x; --y;
    e[i] = {x, y, k};
    if (k == 1) {
      a[x].push_back({y, i});
      a[y].push_back({x, i});
    }
  }

  DFS(0, -1);
  stamp = 0;
  DFS2(0, 0);

  last = pool;
  Node* rt = build(0, n);

  auto Query =
    [&](int x, int y) {
      int tot = 0, cnt = 0;
      while (true) {
        int fx = top[x], fy = top[y];
        if (fx == fy) break;
        if (dep[fx] < dep[fy]) {
          cnt += query(rt, 0, n, tin[fy], tin[y] + 1);
          tot += tin[y] + 1 - tin[fy];
          y = f[fy];
        } else {
          cnt += query(rt, 0, n, tin[fx], tin[x] + 1);
          tot += tin[x] + 1 - tin[fx];
          x = f[fx];
        }
      }
      if (dep[x] > dep[y]) swap(x, y);
      cnt += query(rt, 0, n, tin[x] + 1, tin[y] + 1);
      tot += tin[y] - tin[x];
      return make_pair(tot, cnt);
    };

  auto Insert =
    [&](int x, int y, int bound) {
      while (true) {
        int fx = top[x], fy = top[y];
        if (fx == fy) break;
        if (dep[fx] < dep[fy]) {
          insert(rt, 0, n, tin[fy], tin[y] + 1, bound);
          y = f[fy];
        } else {
          insert(rt, 0, n, tin[fx], tin[x] + 1, bound);
          x = f[fx];
        }
      }
      if (dep[x] > dep[y]) swap(x, y);
      insert(rt, 0, n, tin[x] + 1, tin[y] + 1, bound);
    };
  vector<int> ret(m), vis(m);
  int used = 0;
  for (int i = 0; i < m; ++i) {
    auto [x, y, k] = e[i];
    if (k == 0) {
      auto [tot, cnt] = Query(x, y);
      trace(tot, cnt);
      used += tot - cnt;
      Insert(x, y, used);
      ret[i] = used;
      vis[used] = 1;
      used += 1;
    }
    trace(i, ret);
  }
  vector<pair<int64, int>> can;
  for (int i = 0; i < m; ++i) {
    auto [x, y, k] = e[i];
    if (k == 1) {
      if (dep[x] < dep[y]) swap(x, y);
      int64 bound = query2(rt, 0, n, tin[x]);
      can.push_back({bound, i});
    }
  }
  sort(can.begin(), can.end());
  trace(can);
  int k = 0;
  for (auto& [bound, i] : can) {
    while (vis[k]) ++k;
    ret[i] = k;
    ++k;
  }
  for (auto& x : ret) x += 1;
  out(ret);

  return 0;
}

詳細信息

Test #1:

score: 100
Accepted
time: 2ms
memory: 8272kb

input:

4 5
1 2 0
2 3 1
3 4 1
2 4 0
1 3 1

output:

3 1 4 5 2

result:

ok 5 number(s): "3 1 4 5 2"

Test #2:

score: -100
Wrong Answer
time: 2ms
memory: 8364kb

input:

9 15
1 4 1
3 5 1
3 9 0
1 3 0
2 5 0
5 8 0
6 9 0
8 9 0
1 7 1
1 8 1
6 8 1
4 9 1
2 4 1
3 4 1
4 6 0

output:

4 6 3 5 8 10 12 13 15 9 11 1 7 2 14

result:

wrong answer 1st numbers differ - expected: '1', found: '4'