#include "werewolf.h"
#include <bits/stdc++.h>
using namespace std;
int N, M, Q;
vector<vector<int>> graph;
vector<int> human, wolf;
vector<vector<int>> treeWolf;
vector<vector<int>> treeHuman;
vector<pair<int, int>> prepostWolf;
vector<pair<int, int>> prepostHuman;
vector<vector<int>> jumpWolf;
vector<vector<int>> jumpHuman;
struct ufToMakeArrays {
vector<int> chefs;
void init() {
chefs.resize(N);
for (int i = 0; i<N; i++) {
chefs[i] = i;
}
}
int find(int x) {
if (chefs[x] == x) return x;
return chefs[x] = find(chefs[x]);
}
void unite(int a, int b, bool minmax) {
a = find(a);
b = find(b);
if (a == b) return;
if (minmax?a<b:a>b) swap(a, b);
chefs[b] = a;
}
void makeTreeWolf() {
init();
for (int i = 0; i<N; i++) {
for (int u: graph[i]) {
if (u >= i) continue;
if (find(u) == find(i)) continue;
treeWolf[find(i)].push_back(find(u));
treeWolf[find(u)].push_back(find(i));
unite(u, i, 1);
}
}
}
void makeTreeHuman() {
init();
for (int i = N-1; i>=0; i--) {
for (int u: graph[i]) {
if (u <= i) continue;
if (find(u) == find(i)) continue;
treeHuman[find(i)].push_back(find(u));
treeHuman[find(u)].push_back(find(i));
unite(u, i, 0);
}
}
}
void dfsWolf(int v, int p) {
jumpWolf[0][v] = p;
prepostWolf[v].first = wolf.size();
wolf.push_back(v);
for (int i: treeWolf[v]) {
if (i == p) continue;
dfsWolf(i, v);
}
prepostWolf[v].second = wolf.size()-1;
}
void dfsHuman(int v, int p) {
jumpHuman[0][v] = p;
prepostHuman[v].first = human.size();
human.push_back(v);
for (int i: treeHuman[v]) {
if (i == p) continue;
dfsHuman(i, v);
}
prepostHuman[v].second = human.size()-1;
}
void make() {
treeHuman.assign(N, vector<int>()); treeWolf.assign(N, vector<int>());
makeTreeWolf(); makeTreeHuman();
wolf.clear(); human.clear();
prepostHuman.assign(N, {0, 0});
prepostWolf.assign(N, {0, 0});
jumpHuman.assign(20, vector<int>(N));
jumpWolf.assign(20, vector<int>(N));
dfsWolf(N-1, -1); dfsHuman(0, -1);
for (int i = 1; i<20; i++) {
for (int j = 0; j<N; j++) {
jumpHuman[i][j] = jumpHuman[i-1][j] == -1 ? -1 : jumpHuman[i-1][jumpHuman[i-1][j]];
jumpWolf[i][j] = jumpWolf[i-1][j] == -1 ? -1 : jumpWolf[i-1][jumpWolf[i-1][j]];
}
}
}
};
vector<int> wolfInv, humanInv, humanToWolf;
void makeInv() {
wolfInv.resize(N);
humanInv.resize(N);
for (int i = 0; i<N; i++) wolfInv[wolf[i]] = i;
for (int i = 0; i<N; i++) humanInv[human[i]] = i;
humanToWolf.resize(N);
for (int i = 0; i<N; i++) humanToWolf[i] = wolfInv[human[i]];
}
struct seg {
struct node {
int val=0, left=-1, right=-1;
};
vector<node> tree = {node()};
void build(int v, int rl, int rr) {
if (rl == rr) return;
tree[v].left = tree.size();
tree.push_back(node());
tree[v].right = tree.size();
tree.push_back(node());
int rm = (rl + rr)/2;
build(tree[v].left, rl, rm);
build(tree[v].right, rm+1, rr);
}
int update(int v, int rl, int rr, int pos, int x) {
if (rl == rr) {
int newV = tree.size();
tree.push_back(tree[v]);
tree[newV].val += x;
return newV;
}
int rm = (rl + rr)/2;
int newV = tree.size();
tree.push_back(tree[v]);
if (pos <= rm) tree[newV].left = update(tree[newV].left, rl, rm, pos, x);
else tree[newV].right = update(tree[newV].right, rm+1, rr, pos, x);
tree[newV].val = tree[tree[newV].left].val + tree[tree[newV].right].val;
return newV;
}
int query(int v, int rl, int rr, int ql, int qr) {
if (ql > qr) return 0;
if (rl == ql && rr == qr) return tree[v].val;
int rm = (rl + rr)/2;
return query(tree[v].left, rl, rm, ql, min(qr, rm)) + query(tree[v].right, rm+1, rr, max(ql, rm+1), qr);
}
vector<int> times;
int queryDouble(int hl, int hr, int wl, int wr) {
// cerr << query(times[wr], 0, N-1, hl, hr) << " - " << query(times[wl-1], 0, N-1, hl, hr) << "\n";
// return query(times[wr], 0, N-1, hl, hr) - (wl==0?0:query(times[wl-1], 0, N-1, hl, hr));
return query(times[hr], 0, N-1, wl, wr) - (hl==0?0:query(times[hl-1], 0, N-1, wl, wr));
}
void init() {
build(0, 0, N-1);
for (int i = 0; i<N; i++) {
times.push_back(update(i==0?0:times.back(), 0, N-1, humanToWolf[i], 1));
}
assert((int)times.size() == N);
}
};
pair<int, int> getRangeHuman(int pos, int lim) {
for (int i = 19; i>=0; i--) {
if (jumpHuman[i][pos] != -1 && jumpHuman[i][pos] >= lim) {
pos = jumpHuman[i][pos];
}
}
return prepostHuman[pos];
}
pair<int, int> getRangeWolf(int pos, int lim) {
for (int i = 19; i>=0; i--) {
if (jumpWolf[i][pos] != -1 && jumpWolf[i][pos] <= lim) {
pos = jumpWolf[i][pos];
}
}
return prepostWolf[pos];
}
vector<int> check_validity(int _N, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R) {
N = _N;
M = X.size();
Q = S.size();
graph.clear();
graph.resize(N);
for (int i = 0; i<M; i++) {
graph[X[i]].push_back(Y[i]);
graph[Y[i]].push_back(X[i]);
}
ufToMakeArrays blub;
blub.make();
makeInv();
// for (int i: human) cerr << i << " ";
// cerr << "\n";
// for (int i: wolf) cerr << i << " ";
// cerr << "\n";
seg tree;
tree.init();
vector<int> res(Q, 0);
for (int i = 0; i<Q; i++) {
// cerr << humanInv[S[i]] << "\n";
pair<int, int> rangeHuman = getRangeHuman(S[i], L[i]);
pair<int, int> rangeWolf = getRangeWolf(E[i], R[i]);
// cerr << rangeHuman.first << " " << rangeHuman.second << " " << rangeWolf.first << " " << rangeWolf.second << "\n";
// cerr << tree.queryDouble(rangeHuman.first, rangeHuman.second, rangeWolf.first, rangeWolf.second) << "\n";
if (tree.queryDouble(rangeHuman.first, rangeHuman.second, rangeWolf.first, rangeWolf.second)) res[i] = 1;
}
return res;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
304 KB |
Output is correct |
2 |
Correct |
1 ms |
340 KB |
Output is correct |
3 |
Correct |
1 ms |
212 KB |
Output is correct |
4 |
Correct |
1 ms |
296 KB |
Output is correct |
5 |
Correct |
1 ms |
340 KB |
Output is correct |
6 |
Correct |
1 ms |
300 KB |
Output is correct |
7 |
Correct |
1 ms |
340 KB |
Output is correct |
8 |
Correct |
1 ms |
340 KB |
Output is correct |
9 |
Correct |
1 ms |
340 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
304 KB |
Output is correct |
2 |
Correct |
1 ms |
340 KB |
Output is correct |
3 |
Correct |
1 ms |
212 KB |
Output is correct |
4 |
Correct |
1 ms |
296 KB |
Output is correct |
5 |
Correct |
1 ms |
340 KB |
Output is correct |
6 |
Correct |
1 ms |
300 KB |
Output is correct |
7 |
Correct |
1 ms |
340 KB |
Output is correct |
8 |
Correct |
1 ms |
340 KB |
Output is correct |
9 |
Correct |
1 ms |
340 KB |
Output is correct |
10 |
Correct |
6 ms |
2524 KB |
Output is correct |
11 |
Correct |
6 ms |
2496 KB |
Output is correct |
12 |
Correct |
5 ms |
2520 KB |
Output is correct |
13 |
Correct |
5 ms |
2652 KB |
Output is correct |
14 |
Correct |
6 ms |
2568 KB |
Output is correct |
15 |
Correct |
6 ms |
2652 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
715 ms |
141744 KB |
Output is correct |
2 |
Correct |
934 ms |
143972 KB |
Output is correct |
3 |
Correct |
874 ms |
142448 KB |
Output is correct |
4 |
Correct |
711 ms |
141768 KB |
Output is correct |
5 |
Correct |
681 ms |
141736 KB |
Output is correct |
6 |
Correct |
682 ms |
141828 KB |
Output is correct |
7 |
Correct |
623 ms |
141572 KB |
Output is correct |
8 |
Correct |
814 ms |
144008 KB |
Output is correct |
9 |
Correct |
573 ms |
142360 KB |
Output is correct |
10 |
Correct |
461 ms |
141776 KB |
Output is correct |
11 |
Correct |
427 ms |
141800 KB |
Output is correct |
12 |
Correct |
536 ms |
141708 KB |
Output is correct |
13 |
Correct |
856 ms |
144720 KB |
Output is correct |
14 |
Correct |
799 ms |
144692 KB |
Output is correct |
15 |
Correct |
822 ms |
144756 KB |
Output is correct |
16 |
Correct |
788 ms |
144716 KB |
Output is correct |
17 |
Correct |
617 ms |
141616 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
304 KB |
Output is correct |
2 |
Correct |
1 ms |
340 KB |
Output is correct |
3 |
Correct |
1 ms |
212 KB |
Output is correct |
4 |
Correct |
1 ms |
296 KB |
Output is correct |
5 |
Correct |
1 ms |
340 KB |
Output is correct |
6 |
Correct |
1 ms |
300 KB |
Output is correct |
7 |
Correct |
1 ms |
340 KB |
Output is correct |
8 |
Correct |
1 ms |
340 KB |
Output is correct |
9 |
Correct |
1 ms |
340 KB |
Output is correct |
10 |
Correct |
6 ms |
2524 KB |
Output is correct |
11 |
Correct |
6 ms |
2496 KB |
Output is correct |
12 |
Correct |
5 ms |
2520 KB |
Output is correct |
13 |
Correct |
5 ms |
2652 KB |
Output is correct |
14 |
Correct |
6 ms |
2568 KB |
Output is correct |
15 |
Correct |
6 ms |
2652 KB |
Output is correct |
16 |
Correct |
715 ms |
141744 KB |
Output is correct |
17 |
Correct |
934 ms |
143972 KB |
Output is correct |
18 |
Correct |
874 ms |
142448 KB |
Output is correct |
19 |
Correct |
711 ms |
141768 KB |
Output is correct |
20 |
Correct |
681 ms |
141736 KB |
Output is correct |
21 |
Correct |
682 ms |
141828 KB |
Output is correct |
22 |
Correct |
623 ms |
141572 KB |
Output is correct |
23 |
Correct |
814 ms |
144008 KB |
Output is correct |
24 |
Correct |
573 ms |
142360 KB |
Output is correct |
25 |
Correct |
461 ms |
141776 KB |
Output is correct |
26 |
Correct |
427 ms |
141800 KB |
Output is correct |
27 |
Correct |
536 ms |
141708 KB |
Output is correct |
28 |
Correct |
856 ms |
144720 KB |
Output is correct |
29 |
Correct |
799 ms |
144692 KB |
Output is correct |
30 |
Correct |
822 ms |
144756 KB |
Output is correct |
31 |
Correct |
788 ms |
144716 KB |
Output is correct |
32 |
Correct |
617 ms |
141616 KB |
Output is correct |
33 |
Correct |
956 ms |
142596 KB |
Output is correct |
34 |
Correct |
221 ms |
32276 KB |
Output is correct |
35 |
Correct |
1345 ms |
144488 KB |
Output is correct |
36 |
Correct |
1204 ms |
142112 KB |
Output is correct |
37 |
Correct |
1467 ms |
143808 KB |
Output is correct |
38 |
Correct |
1040 ms |
142580 KB |
Output is correct |
39 |
Correct |
1112 ms |
148344 KB |
Output is correct |
40 |
Correct |
904 ms |
150516 KB |
Output is correct |
41 |
Correct |
913 ms |
143424 KB |
Output is correct |
42 |
Correct |
552 ms |
142080 KB |
Output is correct |
43 |
Correct |
1299 ms |
147864 KB |
Output is correct |
44 |
Correct |
1282 ms |
143820 KB |
Output is correct |
45 |
Correct |
750 ms |
148568 KB |
Output is correct |
46 |
Correct |
888 ms |
148376 KB |
Output is correct |
47 |
Correct |
870 ms |
144928 KB |
Output is correct |
48 |
Correct |
886 ms |
144740 KB |
Output is correct |
49 |
Correct |
878 ms |
144940 KB |
Output is correct |
50 |
Correct |
1010 ms |
144768 KB |
Output is correct |
51 |
Correct |
680 ms |
150936 KB |
Output is correct |
52 |
Correct |
634 ms |
150924 KB |
Output is correct |