QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#120032#5249. Banditshos_lyricRE 0ms0kbC++146.6kb2023-07-06 11:54:032023-07-06 11:54:05

Judging History

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

  • [2023-08-10 23:21:45]
  • System Update: QOJ starts to keep a history of the judgings of all the submissions.
  • [2023-07-06 11:54:05]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2023-07-06 11:54:03]
  • 提交

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 <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; }


template <class T> void bAdd(vector<T> &bit, int pos, const T &val) {
  const int bitN = bit.size();
  for (int x = pos; x < bitN; x |= x + 1) bit[x] += val;
}
template <class T> T bSum(const vector<T> &bit, int pos) {
  T ret = 0;
  for (int x = pos; x > 0; x &= x - 1) ret += bit[x - 1];
  return ret;
}
template <class T> T bSum(const vector<T> &bit, int pos0, int pos1) {
  return bSum(bit, pos1) - bSum(bit, pos0);
}


int N;
vector<int> A, B;
vector<Int> C;
int Q;
vector<Int> R;
vector<int> X, Y;

vector<vector<int>> qssV, qssE;
vector<int> ans;

vector<vector<int>> G;
vector<int> sz, del;
void dfsSz(int u, int p) {
  sz[u] = 1;
  for (const int i : G[u]) {
    const int v = A[i] ^ B[i] ^ u;
    if (v != p) {
      dfsSz(v, u);
      sz[u] += sz[v];
    }
  }
}
string dfsString(int u, int p) {
  ostringstream oss;
  oss << "[" << u;
  for (const int i : G[u]) {
    const int v = A[i] ^ B[i] ^ u;
    if (!del[v] && v != p) {
      oss << " " << dfsString(v, u);
    }
  }
  oss << "]";
  return oss.str();
}
/// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
vector<vector<Int>> css;
// (q, (j, c))
vector<pair<int, pair<int, Int>>> es;
void dfs(int j, int u, int p, int d, Int c) {
  css.back().push_back(c);
  css[j].push_back(c);
  for (const int q : qssV[u]) {
    es.emplace_back(q, make_pair(j, c));
  }
  for (const int i : G[u]) {
    const int v = A[i] ^ B[i] ^ u;
    if (!del[v] && v != p) {
      for (const int q : qssE[i]) {
        es.emplace_back(q, make_pair(j, c + C[i]));
      }
      dfs(j, v, u, d + 1, c + C[i]);
    }
  }
}
/// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
void solveSubtree(int depth, int r) {
#ifdef LOCAL
  cerr << string(2 * depth, ' ') << "solveSubtree " << dfsString(r, -1) << endl;
#endif
  vector<int> is, vs;
  for (const int i : G[r]) {
    const int v = A[i] ^ B[i] ^ r;
    if (!del[v]) {
      is.push_back(i);
      vs.push_back(v);
    }
  }
  const int len = vs.size();
  /// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
  css.assign(len + 1, {});
  es.clear();
  for (const int q : qssV[r]) {
    es.emplace_back(q, make_pair(-1, 0));
  }
  for (int j = 0; j < len; ++j) {
    const int i = is[j], v = vs[j];
    for (const int q : qssE[i]) {
      es.emplace_back(q, make_pair(j, C[i]));
    }
    dfs(j, v, r, 1, C[i]);
  }
  vector<int> tots(len + 1, 0);
  vector<vector<int>> bits(len + 1);
  // edge around root
  vector<int> spe(len, 0);
  for (int j = 0; j <= len; ++j) {
    auto &cs = css[j];
    sort(cs.begin(), cs.end());
    cs.erase(unique(cs.begin(), cs.end()), cs.end());
    bits[j].assign(cs.size(), 0);
  }
  auto ub = [&](int j, Int c) -> int {
    return upper_bound(css[j].begin(), css[j].end(), c) - css[j].begin();
  };
  sort(es.begin(), es.end());
// cerr<<"css = "<<css<<endl;
// cerr<<"es = "<<es<<endl;
  for (const auto &e : es) {
    const int q = e.first;
    const int j = e.second.first;
    const Int c = e.second.second;
    if (~X[q]) {
      if (c <= R[q]) {
        // add to <= R-c
        ++tots[len];
        bAdd(bits[len], ub(len, R[q] - c), +1);
        if (~j) {
          ++tots[j];
          bAdd(bits[j], ub(len, R[q] - c), +1);
          ++spe[j];
        }
      }
    } else {
      int sum = 0;
      sum += (tots[len] - bSum(bits[len], ub(len, c)));
      sum -= (tots[j] - bSum(bits[j], ub(j, c)));
      if (A[Y[q]] == r || B[Y[q]] == r) {
        sum += spe[j];
      }
// cerr<<"  e = "<<e<<": sum = "<<sum<<endl;
      ans[q] += sum;
    }
  }
  /// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
void solveRec(int depth, int u) {
  for (; ; ) {
    int vm = -1;
    for (const int i : G[u]) {
      const int v = A[i] ^ B[i] ^ u;
      if (!del[v]) {
        if (!~vm || sz[vm] < sz[v]) {
          vm = v;
        }
      }
    }
    if (!~vm || 2 * sz[vm] <= sz[u]) {
      solveSubtree(depth, u);
      del[u] = 1;
      for (const int i : G[u]) {
        const int v = A[i] ^ B[i] ^ u;
        if (!del[v]) {
          solveRec(depth + 1, v);
        }
      }
      break;
    } else {
      sz[u] -= sz[vm];
      sz[vm] += sz[u];
      u = vm;
    }
  }
}
void centroidDecomp() {
  sz.assign(N, 0);
  dfsSz(0, -1);
  del.assign(N, 0);
  solveRec(0, 0);
}


int main() {
  for (; ~scanf("%d", &N); ) {
    A.resize(N - 1);
    B.resize(N - 1);
    C.resize(N - 1);
    for (int i = 0; i < N - 1; ++i) {
      scanf("%d%d%lld", &A[i], &B[i], &C[i]);
      --A[i];
      --B[i];
assert(C[i]!=0);
    }
    scanf("%d", &Q);
    R.assign(Q, -1);
    X.assign(Q, -1);
    Y.assign(Q, -1);
    for (int q = 0; q < Q; ++q) {
      char typ;
      scanf(" %c", &typ);
      if (typ == '+') {
        scanf("%d%lld", &X[q], &R[q]);
        --X[q];
      } else {
        scanf("%d", &Y[q]);
        --Y[q];
      }
    }
    
    G.assign(N, {});
    for (int i = 0; i < N - 1; ++i) {
      G[A[i]].push_back(i);
      G[B[i]].push_back(i);
    }
    
    qssV.assign(N, {});
    qssE.assign(N - 1, {});
    for (int q = 0; q < Q; ++q) {
      if (~X[q]) {
        qssV[X[q]].push_back(q);
      } else {
        qssE[Y[q]].push_back(q);
      }
    }
    ans.assign(Q, 0);
    
    centroidDecomp();
    
    for (int q = 0; q < Q; ++q) if (!~X[q]) {
      printf("%d\n", ans[q]);
    }
  }
  return 0;
}

詳細信息

Test #1:

score: 0
Dangerous Syscalls

input:

100000
2670 75097 4080
87477 75802 1712
51835 36626 2883
19412 25923 5852
23976 19312 2520
82536 19514 2492
27160 66601 4483
99087 15088 3504
47050 58820 2964
37063 5696 9901
7717 1496 4891
79136 5448 4340
22575 81285 9289
96280 3803 9877
41980 32139 2855
44236 64938 3298
5983 99947 9666
95856 62545...

output:


result: