#include "werewolf.h"
#include <bits/stdc++.h>
using namespace std;
const int maxN = 400000;
typedef pair<int,int> ii;
struct UFDS{
int p[maxN];
void reset(int n){
for(int i = 0;i < n;i++) p[i] = i;
}
int findSet(int u){
if(p[u] == u) return u;
else{
p[u] = findSet(p[u]);
return p[u]; ///use path compression only
}
}
void unionSet(int u, int v){
u = findSet(u);
v = findSet(v);
if(u == v) return;
if(u > v) swap(u,v);
p[u] = v; ///don't union by rank, instead return the largest value to make tree building easier
}
};
struct query{
int start;
int end;
int L;
int R;
int id;
int humanSubtree; ///idx of subtree
int humanLow; ///preorder left endpoint
int humanHigh; ///preorder right endpoint
int wolfSubtree; ///idx of subtree
int wolfLow; ///preorder left endpoint
int wolfHigh; ///preorder right endpoint
};
struct edge{
int u;
int v;
int w;
};
struct tree{
vector<int> child[maxN];
int low[maxN];
int high[maxN];
int cnt = 0;
void addEdge(int parent, int c){
child[parent].push_back(c);
}
///basically like a preorder, but don't label the non-leaves
void dfs(int u){
low[u] = 102345678;
high[u] = -1;
if(child[u].empty()){
low[u] = cnt;
high[u] = cnt;
cnt++;
return;
}
for(int v : child[u]){
dfs(v);
low[u] = min(low[u],low[v]);
high[u] = max(high[u],high[v]);
}
}
};
struct segment{
int seg[maxN]; int n;
void create(int nn){
n = nn;
for(int i = 0;i < 2*n;i++) seg[i] = -1e8;
}
void update(int i, int v){
i += n;
while(i > 0){
seg[i] = max(seg[i],v);
i >>= 1;
}
}
int Query(int l, int r){
int ans = -1e8;
for(l += n, r += n;l < r;l >>= 1, r >>= 1){
if(l&1){
ans = max(ans, seg[l]);
l++;
}
if(r&1){
r--;
ans = max(ans, seg[r]);
}
}
return ans;
}
};
bool edgeComp(edge a, edge b){
return a.w < b.w;
}
bool queryCompHuman(query a, query b){
return a.L > b.L;
}
bool queryCompWolf(query a, query b){
return a.R < b.R;
}
bool queryHighComp(query a, query b){
return a.humanHigh < b.humanHigh;
}
std::vector<int> check_validity(int n, std::vector<int> X, std::vector<int> Y,
std::vector<int> S, std::vector<int> E,
std::vector<int> L, std::vector<int> R) {
int m = X.size();
int q = S.size();
vector<int> answer;
answer.assign(q,0);
query queries[q+1];
for(int i = 0;i < q;i++){
queries[i] = {S[i],E[i],L[i],R[i],i,-1,-1,-1,-1};
}
edge edges[m];
UFDS uf;
tree human; tree wolf;
///Building the tree for the start/human form
///In the new tree, if a node has a value X, all leaves in that subtree will be reachable if L = X, (i.e. all leaves nodes have value >= X)
for(int i = 0;i < m;i++) edges[i] = {X[i],Y[i],min(X[i],Y[i])};
sort(edges,edges+m,edgeComp);
reverse(edges,edges+m); ///decreasing weight
sort(queries,queries+q,queryCompHuman); ///decreasing L
queries[q].L = -1; ///dummy element to ensure entire tree is comepleted
uf.reset(2*n);
int newNode = n;
int edgePtr = 0;
for(int i = 0;i <= q;i++){
while(edgePtr < m && edges[edgePtr].w >= queries[i].L){
int u = uf.findSet(edges[edgePtr].u);
int v = uf.findSet(edges[edgePtr].v);
edgePtr++;
if(u == v) continue;
///connect the two greatest parents to another parent
uf.unionSet(u,newNode);
uf.unionSet(v,newNode);
human.addEdge(newNode,u);
human.addEdge(newNode,v);
newNode++;
}
///the representitive subtree is the subtree of the greatest parent at the current moment
if(i != q) queries[i].humanSubtree = uf.findSet(queries[i].start);
}
///Building the tree for the end/wolf form
///In the new tree, if a node has a value X, all leaves in that subtree will be reachable if R = X, (i.e. all leaves nodes have value <= X)
for(int i = 0;i < m;i++) edges[i] = {X[i],Y[i],max(X[i],Y[i])};
sort(edges,edges+m,edgeComp); ///increasing weight
sort(queries,queries+q,queryCompWolf); ///increasing R
queries[q].R = 1e7; ///dummy element to ensure entire tree is comepleted
uf.reset(2*n);
newNode = n;
edgePtr = 0;
for(int i = 0;i <= q;i++){
while(edgePtr < m && edges[edgePtr].w <= queries[i].R){
int u = uf.findSet(edges[edgePtr].u);
int v = uf.findSet(edges[edgePtr].v);
edgePtr++;
if(u == v) continue;
///connect the two greatest parents to another parent
uf.unionSet(u,newNode);
uf.unionSet(v,newNode);
wolf.addEdge(newNode,u);
wolf.addEdge(newNode,v);
newNode++;
}
///the representitive subtree is the subtree of the greatest parent at the current moment
if(i != q) queries[i].wolfSubtree = uf.findSet(queries[i].end);
}
///Now, we run a preorder on the tree, but don't label to edges. This way, we can convert each query into checking whether two sets of elements have any element in common
human.dfs(2 * n - 2);
wolf.dfs(2 * n - 2);
//for(int i = 0;i < 2*n-1;i++){
// cout << human.low[i] << " " << human.high[i] << " " << wolf.low[i] << " " << wolf.high[i] << "\n";
//}
///Low and High represent the ranges, we need to check if the human range and the wolf range intersect
///Note: intersect here means the following:
///In each of the human tree, each node on the original graph corresponds to another number on the human tree
///Same for the wolf tree
///Each query is a consecutive range of numbers of both trees.
///If we convert each of the numbers in the ranges of the trees back to the original index, we query whether there exist a vertex that is shared on both graphs
for(int i = 0;i < q;i++){
queries[i].humanLow = human.low[queries[i].humanSubtree];
queries[i].humanHigh = human.high[queries[i].humanSubtree];
queries[i].wolfLow = wolf.low[queries[i].wolfSubtree];
queries[i].wolfHigh = wolf.high[queries[i].wolfSubtree];
//cout << queries[i].id << " " << queries[i].humanSubtree << " " << queries[i].wolfSubtree << " " << queries[i].humanLow << " " << queries[i].humanHigh << " " << queries[i].wolfLow << " " << queries[i].wolfHigh << "\n";
}
///Use a segment tree to answer this type of queries
segment seg;
seg.create(n);
///convert stores which number of the human tree corresponds to which number on the wolf tree
ii convert[n];
for(int i = 0;i < n;i++) convert[i] = ii(human.low[i],wolf.low[i]);
sort(convert,convert + n);
sort(queries,queries+q,queryHighComp);
int ptr = 0;
for(int i = 0;i < q;i++){
query qu = queries[i];
while(ptr < n && qu.humanHigh >= convert[ptr].first){
seg.update(convert[ptr].second, convert[ptr].first);
//cout << convert[ptr].second << " " << convert[ptr].first << "\n";
ptr++;
}
//cout << qu.id << " " << seg.Query(qu.wolfLow, qu.wolfHigh + 1) << "\n";
if(seg.Query(qu.wolfLow, qu.wolfHigh + 1) >= qu.humanLow){
answer[qu.id] = 1;
}
else{
answer[qu.id] = 0;
}
}
return answer;
}
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
19192 KB |
Output is correct |
2 |
Correct |
20 ms |
19192 KB |
Output is correct |
3 |
Correct |
23 ms |
19192 KB |
Output is correct |
4 |
Correct |
19 ms |
19192 KB |
Output is correct |
5 |
Correct |
19 ms |
19192 KB |
Output is correct |
6 |
Correct |
19 ms |
19320 KB |
Output is correct |
7 |
Correct |
19 ms |
19192 KB |
Output is correct |
8 |
Correct |
19 ms |
19192 KB |
Output is correct |
9 |
Correct |
19 ms |
19192 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
19192 KB |
Output is correct |
2 |
Correct |
20 ms |
19192 KB |
Output is correct |
3 |
Correct |
23 ms |
19192 KB |
Output is correct |
4 |
Correct |
19 ms |
19192 KB |
Output is correct |
5 |
Correct |
19 ms |
19192 KB |
Output is correct |
6 |
Correct |
19 ms |
19320 KB |
Output is correct |
7 |
Correct |
19 ms |
19192 KB |
Output is correct |
8 |
Correct |
19 ms |
19192 KB |
Output is correct |
9 |
Correct |
19 ms |
19192 KB |
Output is correct |
10 |
Correct |
25 ms |
19960 KB |
Output is correct |
11 |
Correct |
25 ms |
19960 KB |
Output is correct |
12 |
Correct |
26 ms |
19900 KB |
Output is correct |
13 |
Correct |
26 ms |
19964 KB |
Output is correct |
14 |
Correct |
26 ms |
20000 KB |
Output is correct |
15 |
Correct |
27 ms |
20028 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
733 ms |
72112 KB |
Output is correct |
2 |
Correct |
602 ms |
73808 KB |
Output is correct |
3 |
Correct |
608 ms |
72316 KB |
Output is correct |
4 |
Correct |
642 ms |
72312 KB |
Output is correct |
5 |
Correct |
653 ms |
72184 KB |
Output is correct |
6 |
Correct |
663 ms |
72304 KB |
Output is correct |
7 |
Correct |
636 ms |
72200 KB |
Output is correct |
8 |
Correct |
589 ms |
73848 KB |
Output is correct |
9 |
Correct |
543 ms |
72184 KB |
Output is correct |
10 |
Correct |
572 ms |
72184 KB |
Output is correct |
11 |
Correct |
589 ms |
72288 KB |
Output is correct |
12 |
Correct |
621 ms |
72284 KB |
Output is correct |
13 |
Correct |
610 ms |
73720 KB |
Output is correct |
14 |
Correct |
629 ms |
73848 KB |
Output is correct |
15 |
Correct |
618 ms |
73800 KB |
Output is correct |
16 |
Correct |
613 ms |
73900 KB |
Output is correct |
17 |
Correct |
647 ms |
72140 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
19192 KB |
Output is correct |
2 |
Correct |
20 ms |
19192 KB |
Output is correct |
3 |
Correct |
23 ms |
19192 KB |
Output is correct |
4 |
Correct |
19 ms |
19192 KB |
Output is correct |
5 |
Correct |
19 ms |
19192 KB |
Output is correct |
6 |
Correct |
19 ms |
19320 KB |
Output is correct |
7 |
Correct |
19 ms |
19192 KB |
Output is correct |
8 |
Correct |
19 ms |
19192 KB |
Output is correct |
9 |
Correct |
19 ms |
19192 KB |
Output is correct |
10 |
Correct |
25 ms |
19960 KB |
Output is correct |
11 |
Correct |
25 ms |
19960 KB |
Output is correct |
12 |
Correct |
26 ms |
19900 KB |
Output is correct |
13 |
Correct |
26 ms |
19964 KB |
Output is correct |
14 |
Correct |
26 ms |
20000 KB |
Output is correct |
15 |
Correct |
27 ms |
20028 KB |
Output is correct |
16 |
Correct |
733 ms |
72112 KB |
Output is correct |
17 |
Correct |
602 ms |
73808 KB |
Output is correct |
18 |
Correct |
608 ms |
72316 KB |
Output is correct |
19 |
Correct |
642 ms |
72312 KB |
Output is correct |
20 |
Correct |
653 ms |
72184 KB |
Output is correct |
21 |
Correct |
663 ms |
72304 KB |
Output is correct |
22 |
Correct |
636 ms |
72200 KB |
Output is correct |
23 |
Correct |
589 ms |
73848 KB |
Output is correct |
24 |
Correct |
543 ms |
72184 KB |
Output is correct |
25 |
Correct |
572 ms |
72184 KB |
Output is correct |
26 |
Correct |
589 ms |
72288 KB |
Output is correct |
27 |
Correct |
621 ms |
72284 KB |
Output is correct |
28 |
Correct |
610 ms |
73720 KB |
Output is correct |
29 |
Correct |
629 ms |
73848 KB |
Output is correct |
30 |
Correct |
618 ms |
73800 KB |
Output is correct |
31 |
Correct |
613 ms |
73900 KB |
Output is correct |
32 |
Correct |
647 ms |
72140 KB |
Output is correct |
33 |
Correct |
687 ms |
72228 KB |
Output is correct |
34 |
Correct |
511 ms |
57720 KB |
Output is correct |
35 |
Correct |
698 ms |
74232 KB |
Output is correct |
36 |
Correct |
685 ms |
72440 KB |
Output is correct |
37 |
Correct |
695 ms |
73208 KB |
Output is correct |
38 |
Correct |
697 ms |
72704 KB |
Output is correct |
39 |
Correct |
665 ms |
76884 KB |
Output is correct |
40 |
Correct |
779 ms |
80936 KB |
Output is correct |
41 |
Correct |
712 ms |
72824 KB |
Output is correct |
42 |
Correct |
641 ms |
72568 KB |
Output is correct |
43 |
Correct |
741 ms |
78300 KB |
Output is correct |
44 |
Correct |
711 ms |
73268 KB |
Output is correct |
45 |
Correct |
626 ms |
77356 KB |
Output is correct |
46 |
Correct |
633 ms |
77120 KB |
Output is correct |
47 |
Correct |
612 ms |
74004 KB |
Output is correct |
48 |
Correct |
605 ms |
73848 KB |
Output is correct |
49 |
Correct |
611 ms |
73988 KB |
Output is correct |
50 |
Correct |
627 ms |
73848 KB |
Output is correct |
51 |
Correct |
786 ms |
81244 KB |
Output is correct |
52 |
Correct |
775 ms |
81252 KB |
Output is correct |