QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#768912#8557. Goldberg MachineSunsetGlow95RE 0ms0kbC++144.0kb2024-11-21 15:11:222024-11-21 15:11:31

Judging History

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

  • [2024-11-21 15:11:31]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-11-21 15:11:22]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
const int MXN = 100005;
const int MXL = 200005;
const int BW = 1800;
const int BC = 120;
int N, init[MXN], fa[MXN], delta[MXN], L;
int seq[MXL], lev[MXL], tag[BC], mnv[BC], mxv[BC], cnt[BC][BW], sum[BC][BW];
int Q;
deque<int> es[MXN];
vector<int> sid[MXN];

template<typename T = int>
T read() {
  T x(0);
  int c(getchar());
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') x = x * 10 + (c - '0'), c = getchar();
  return x;
}
void write(int x) {
  static char buf[11];
  assert(x);
  int d(0);
  while (x) buf[d++] = x % 10 + '0', x /= 10;
  while (d) putchar(buf[--d]);
}

void getfa(int p, int f) {
  fa[p] = f;
  for (int q : es[p]) if (q != f) getfa(q, p);
}
void getseq(int p, int l) {
  for (int i(0); i != es[p].size(); ++i) {
    int q(es[p][i]);
    sid[p].push_back(L);
    lev[L] = l + (i < init[p]);
    seq[L++] = q;
    if (q != fa[p]) getseq(q, l + (i < init[p]));
  }
}

void build_block(int bi) {
  mnv[bi] = N, mxv[bi] = 0;
  for (int i(bi * BW); i != min((bi + 1) * BW, L); ++i)
    lev[i] += tag[bi],
    mnv[bi] = min(mnv[bi], lev[i]),
    mxv[bi] = max(mxv[bi], lev[i]);
  tag[bi] = 0;
  for (int i(0); i <= mxv[bi] - mnv[bi]; ++i) cnt[bi][i] = 0;
  for (int i(bi * BW); i != min((bi + 1) * BW, L); ++i)
    ++cnt[bi][lev[i] - mnv[bi]];
  for (int i(1); i <= mxv[bi] - mnv[bi]; ++i)
    cnt[bi][i] += cnt[bi][i - 1],
    sum[bi][i] = sum[bi][i - 1] + cnt[bi][i - 1];
}

void add(int l, int r, int dv) {
//cout << "add " << l << ' ' << r << ' ' << dv << endl;
  if (l / BW == (r - 1) / BW) {
    for (int i(l); i != r; ++i) lev[i] += dv;
    build_block(l / BW);
  } else {
    for (int i(l); i / BW == l / BW; ++i) lev[i] += dv;
    build_block(l / BW);
    for (int i(l / BW + 1); i != r / BW; ++i)
      tag[i] += dv, mnv[i] += dv, mxv[i] += dv;
    for (int i(r / BW * BW); i != r; ++i) lev[i] += dv;
    if (r != r / BW * BW) build_block(r / BW);
  }
}

inline ll calc_in_block(int bi, ll x) {
  if (x <= mnv[bi]) return 0;
  if (x <= mxv[bi]) return sum[bi][x - mnv[bi]];
  return sum[bi][mxv[bi] - mnv[bi]] +
         cnt[bi][mxv[bi] - mnv[bi]] * (x - mxv[bi]);
}
inline int getcnt(int bi, ll d) {
  if (d < mnv[bi]) return 0;
  return cnt[bi][min<ll>(d, mxv[bi]) - mnv[bi]];
}

int main() {
  freopen("walk.in", "r", stdin);
  freopen("walk.out", "w", stdout);
  N = read();
  for (int i(0); i != N; ++i) {
    es[i].resize(read()), init[i] = read();
    for (auto &j : es[i]) j = read() - 1;
  }
  getfa(0, -1);
  for (int i(1); i != N; ++i) {
    while (es[i].back() != fa[i])
      es[i].push_front(es[i].back()), es[i].pop_back(), ++delta[i];
    init[i] = (init[i] + delta[i]) % es[i].size();
  }
  getseq(0, 0);
//for (int i(0); i != L; ++i) cout << seq[i] << ',';
//cout << endl;
//for (int i(0); i != L; ++i) cout << lev[i] << ',';
//cout << endl;
  for (int i(0); i * BW < L; ++i) build_block(i);
  Q = read();
  for (char op(0); Q--;) {
    scanf(" %c", &op);
    if (op == 'C') {
      int x(read() - 1);
      int y((read() + delta[x]) % es[x].size());
      if (y < init[x]) add(sid[x][y], sid[x][init[x]], -1);
      if (y > init[x]) add(sid[x][init[x]], sid[x][y], 1);
      init[x] = y;
    } else {
      ll id(read<ll>() - 1);
      ll lb(0), rb(id / L + N + 1);
      while (rb - lb > 1) {
        ll m((lb + rb) >> 1);
        ll csum(0);
        for (int i(0); i * BW < L; ++i) csum += calc_in_block(i, m);
        if (csum <= id) lb = m;
        else rb = m;
      }
      for (int i(0); i * BW < L; ++i) id -= calc_in_block(i, lb);
      int bi(0);
      while (true) {
        int c(getcnt(bi, lb));
        if (id >= c) id -= c, ++bi;
        else break;
      }
      int oid(bi * BW);
      while (true) {
        if (lev[oid] + tag[bi] <= lb) {
          if (!id) break;
          --id;
        }
        ++oid;
      }
//    cout << oid << ' ' << bi << ' ' << lb << endl;
      write(seq[oid] + 1), putchar('\n');
    }
  }
  return 0;
}

详细

Test #1:

score: 0
Dangerous Syscalls

input:

7
2 0 2 3
3 0 1 4 5
3 0 1 6 7
1 0 2
1 0 2
1 0 3
1 0 3
5
Q 10
C 2 1
Q 10
C 3 2
Q 10

output:


result: