답안 #229690

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
229690 2020-05-05T22:54:11 Z xiaowuc1 트리 (KOI16_tree) C++14
9 / 100
530 ms 47736 KB
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <complex>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <vector>

using namespace std;

// BEGIN NO SAD
#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) x.begin(), x.end()
#define sz(x) (int)(x).size()
#define derr if(1) cerr
typedef vector<int> vi;
// END NO SAD

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<vector<ll>> matrix;
typedef pair<int, pii> state;

const int KOOSAGA_DEPTH = 18;
const int KOOSAGA_SZ = 1 << KOOSAGA_DEPTH;
bool koosagatree[2 * KOOSAGA_SZ];
void upd(int idx) {
  idx += KOOSAGA_SZ;
  while(idx) {
    koosagatree[idx] = true;
    idx /= 2;
  }
}
bool qry(int lhs, int rhs) {
  lhs += KOOSAGA_SZ;
  rhs += KOOSAGA_SZ;
  while(lhs <= rhs) {
    if(lhs == rhs) return koosagatree[lhs];
    if(lhs%2) if(koosagatree[lhs++]) return true;
    if(rhs%2==0) if(koosagatree[rhs--]) return true;
    lhs /= 2;
    rhs /= 2;
  }
  return false;
}

vector<int> children[KOOSAGA_SZ];
int vertextoedge[KOOSAGA_SZ]; // vertextoedge[i] gives koosaga tree ID for (parent of i, i) edge
int treedepth[KOOSAGA_SZ];
int treetop[KOOSAGA_SZ];
int treesz[KOOSAGA_SZ];
int lca[KOOSAGA_SZ][KOOSAGA_DEPTH];

bool _sort_by_sz(int a, int b) {
  return treesz[a] > treesz[b];
}
void dfsforhld(int curr, int top, int& id) {
  treetop[curr] = top;
  if(sz(children[curr]) == 0) return;
  sort(all(children[curr]), _sort_by_sz);
  vertextoedge[children[curr][0]] = id++;
  dfsforhld(children[curr][0], top, id);
  for(int i = 1; i < sz(children[curr]); i++) {
    vertextoedge[children[curr][i]] = id++;
    dfsforhld(children[curr][i], children[curr][i], id);
  }
}
void dfsforsz(int curr) {
  treesz[curr] = 1;
  for(int out: children[curr]) {
    treedepth[out] = treedepth[curr] + 1;
    dfsforsz(out);
    treesz[curr] += treesz[out];
  }
}

int getlca(int a, int b) {
  if(treedepth[a] < treedepth[b]) swap(a, b);
  for(int d = KOOSAGA_DEPTH-1; d >= 0; d--) {
    if(treedepth[a] - (1<<d) >= treedepth[b]) a = lca[a][d];
  }
  assert(treedepth[a] == treedepth[b]);
  for(int d = KOOSAGA_DEPTH-1; d >= 0; d--) {
    if(lca[a][d] != lca[b][d]) {
      a = lca[a][d];
      b = lca[b][d];
    }
  }
  while(a != b) {
    a = lca[a][0];
    b = lca[b][0];
  }
  return a;
}

bool pathqry(int root, int curr) {
  assert(treedepth[root] <= treedepth[curr]);
  while(treedepth[curr] > treedepth[root]) {
    if(curr == treetop[curr]) {
      if(qry(vertextoedge[curr], vertextoedge[curr])) return false;
      curr = lca[curr][0];
      continue;
    }
    if(treedepth[treetop[curr]] >= treedepth[root]) {
      // go all the way to top[curr]
      int nume = treedepth[curr] - treedepth[treetop[curr]] - 1;
      assert(nume >= 0);
      if(qry(vertextoedge[curr]-nume, vertextoedge[curr])) return false;
      curr = treetop[curr];
      continue;
    }
    // go all the way to root
    int nume = treedepth[curr] - treedepth[root] - 1;
    assert(nume >= 0);
    if(qry(vertextoedge[curr]-nume, vertextoedge[curr])) return false;
    return true;
  }
  return true;
}

bool connected(int a, int b) {
  int r = getlca(a, b);
  assert(r);
  return pathqry(r, a) && pathqry(r, b);
}

void solve() {
  int n, q;
  cin >> n >> q;
  for(int i = 2; i <= n; i++) {
    cin >> lca[i][0];
    children[lca[i][0]].push_back(i);
  }
  dfsforsz(1);
  for(int d = 1; d < KOOSAGA_DEPTH; d++) {
    for(int i = 1; i <= n; i++) {
      lca[i][d] = lca[lca[i][d-1]][d-1];
    }
  }
  {
    int id = 0;
    dfsforhld(1, 1, id);
  }
  while(q--) {
    int a, b, t;
    cin >> a >> b >> t;
    if(connected(a, b)) {
      cout << "YES\n";
      if(t==1) upd(vertextoedge[a]);
    }
    else {
      cout << "NO\n";
      if(t==1) upd(vertextoedge[b]);
    }
  }
}
// are there edge cases (N=1?)
// are array sizes proper (scaled by proper constant, for example 2* for koosaga tree)
// integer overflow?
// DS reset properly between test cases

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL); cout.tie(NULL);
  solve();
}
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 6784 KB Output is correct
2 Correct 9 ms 6784 KB Output is correct
3 Correct 10 ms 6784 KB Output is correct
4 Correct 9 ms 6784 KB Output is correct
5 Correct 9 ms 6784 KB Output is correct
6 Correct 9 ms 6784 KB Output is correct
7 Correct 9 ms 6784 KB Output is correct
8 Correct 9 ms 6784 KB Output is correct
9 Correct 9 ms 6784 KB Output is correct
10 Correct 9 ms 6784 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 6784 KB Output is correct
2 Correct 9 ms 6784 KB Output is correct
3 Correct 10 ms 6784 KB Output is correct
4 Correct 9 ms 6784 KB Output is correct
5 Correct 9 ms 6784 KB Output is correct
6 Correct 9 ms 6784 KB Output is correct
7 Correct 9 ms 6784 KB Output is correct
8 Correct 9 ms 6784 KB Output is correct
9 Correct 9 ms 6784 KB Output is correct
10 Correct 9 ms 6784 KB Output is correct
11 Correct 9 ms 6656 KB Output is correct
12 Correct 9 ms 6656 KB Output is correct
13 Correct 9 ms 6656 KB Output is correct
14 Correct 9 ms 6656 KB Output is correct
15 Correct 9 ms 6656 KB Output is correct
16 Incorrect 9 ms 6656 KB Output isn't correct
17 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 6784 KB Output is correct
2 Correct 9 ms 6784 KB Output is correct
3 Correct 10 ms 6784 KB Output is correct
4 Correct 9 ms 6784 KB Output is correct
5 Correct 9 ms 6784 KB Output is correct
6 Correct 9 ms 6784 KB Output is correct
7 Correct 9 ms 6784 KB Output is correct
8 Correct 9 ms 6784 KB Output is correct
9 Correct 9 ms 6784 KB Output is correct
10 Correct 9 ms 6784 KB Output is correct
11 Correct 9 ms 6656 KB Output is correct
12 Correct 9 ms 6656 KB Output is correct
13 Correct 9 ms 6656 KB Output is correct
14 Correct 9 ms 6656 KB Output is correct
15 Correct 9 ms 6656 KB Output is correct
16 Incorrect 9 ms 6656 KB Output isn't correct
17 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 6784 KB Output is correct
2 Correct 9 ms 6784 KB Output is correct
3 Correct 10 ms 6784 KB Output is correct
4 Correct 9 ms 6784 KB Output is correct
5 Correct 9 ms 6784 KB Output is correct
6 Correct 9 ms 6784 KB Output is correct
7 Correct 9 ms 6784 KB Output is correct
8 Correct 9 ms 6784 KB Output is correct
9 Correct 9 ms 6784 KB Output is correct
10 Correct 9 ms 6784 KB Output is correct
11 Correct 530 ms 47464 KB Output is correct
12 Correct 492 ms 47188 KB Output is correct
13 Correct 467 ms 47352 KB Output is correct
14 Correct 476 ms 47308 KB Output is correct
15 Correct 464 ms 47244 KB Output is correct
16 Correct 475 ms 47540 KB Output is correct
17 Incorrect 337 ms 47736 KB Output isn't correct
18 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 9 ms 6784 KB Output is correct
2 Correct 9 ms 6784 KB Output is correct
3 Correct 10 ms 6784 KB Output is correct
4 Correct 9 ms 6784 KB Output is correct
5 Correct 9 ms 6784 KB Output is correct
6 Correct 9 ms 6784 KB Output is correct
7 Correct 9 ms 6784 KB Output is correct
8 Correct 9 ms 6784 KB Output is correct
9 Correct 9 ms 6784 KB Output is correct
10 Correct 9 ms 6784 KB Output is correct
11 Correct 9 ms 6656 KB Output is correct
12 Correct 9 ms 6656 KB Output is correct
13 Correct 9 ms 6656 KB Output is correct
14 Correct 9 ms 6656 KB Output is correct
15 Correct 9 ms 6656 KB Output is correct
16 Incorrect 9 ms 6656 KB Output isn't correct
17 Halted 0 ms 0 KB -