#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);
///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];
}
///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);
///So basically we build a range max segment tree on the wolf indeces
///For all human indeces lower than qu.humanHigh, we update the human index on the wolf segment tree
///If the range max of the wolf segment tree is larger than q.humanLow, then we can conclude that the two ranges intersect
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);
ptr++;
}
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 |
19320 KB |
Output is correct |
2 |
Correct |
19 ms |
19192 KB |
Output is correct |
3 |
Correct |
18 ms |
19192 KB |
Output is correct |
4 |
Correct |
49 ms |
19196 KB |
Output is correct |
5 |
Correct |
23 ms |
19192 KB |
Output is correct |
6 |
Correct |
19 ms |
19192 KB |
Output is correct |
7 |
Correct |
19 ms |
19192 KB |
Output is correct |
8 |
Correct |
19 ms |
19192 KB |
Output is correct |
9 |
Correct |
25 ms |
19216 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
19320 KB |
Output is correct |
2 |
Correct |
19 ms |
19192 KB |
Output is correct |
3 |
Correct |
18 ms |
19192 KB |
Output is correct |
4 |
Correct |
49 ms |
19196 KB |
Output is correct |
5 |
Correct |
23 ms |
19192 KB |
Output is correct |
6 |
Correct |
19 ms |
19192 KB |
Output is correct |
7 |
Correct |
19 ms |
19192 KB |
Output is correct |
8 |
Correct |
19 ms |
19192 KB |
Output is correct |
9 |
Correct |
25 ms |
19216 KB |
Output is correct |
10 |
Correct |
26 ms |
19960 KB |
Output is correct |
11 |
Correct |
26 ms |
19988 KB |
Output is correct |
12 |
Correct |
26 ms |
19960 KB |
Output is correct |
13 |
Correct |
26 ms |
20028 KB |
Output is correct |
14 |
Correct |
26 ms |
19960 KB |
Output is correct |
15 |
Correct |
28 ms |
20088 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
664 ms |
63956 KB |
Output is correct |
2 |
Correct |
600 ms |
65512 KB |
Output is correct |
3 |
Correct |
611 ms |
63992 KB |
Output is correct |
4 |
Correct |
637 ms |
64060 KB |
Output is correct |
5 |
Correct |
688 ms |
64192 KB |
Output is correct |
6 |
Correct |
710 ms |
64248 KB |
Output is correct |
7 |
Correct |
629 ms |
63992 KB |
Output is correct |
8 |
Correct |
574 ms |
65600 KB |
Output is correct |
9 |
Correct |
544 ms |
64248 KB |
Output is correct |
10 |
Correct |
571 ms |
63996 KB |
Output is correct |
11 |
Correct |
583 ms |
63992 KB |
Output is correct |
12 |
Correct |
650 ms |
64120 KB |
Output is correct |
13 |
Correct |
624 ms |
65784 KB |
Output is correct |
14 |
Correct |
633 ms |
65636 KB |
Output is correct |
15 |
Correct |
606 ms |
65708 KB |
Output is correct |
16 |
Correct |
628 ms |
65680 KB |
Output is correct |
17 |
Correct |
634 ms |
63964 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
19 ms |
19320 KB |
Output is correct |
2 |
Correct |
19 ms |
19192 KB |
Output is correct |
3 |
Correct |
18 ms |
19192 KB |
Output is correct |
4 |
Correct |
49 ms |
19196 KB |
Output is correct |
5 |
Correct |
23 ms |
19192 KB |
Output is correct |
6 |
Correct |
19 ms |
19192 KB |
Output is correct |
7 |
Correct |
19 ms |
19192 KB |
Output is correct |
8 |
Correct |
19 ms |
19192 KB |
Output is correct |
9 |
Correct |
25 ms |
19216 KB |
Output is correct |
10 |
Correct |
26 ms |
19960 KB |
Output is correct |
11 |
Correct |
26 ms |
19988 KB |
Output is correct |
12 |
Correct |
26 ms |
19960 KB |
Output is correct |
13 |
Correct |
26 ms |
20028 KB |
Output is correct |
14 |
Correct |
26 ms |
19960 KB |
Output is correct |
15 |
Correct |
28 ms |
20088 KB |
Output is correct |
16 |
Correct |
664 ms |
63956 KB |
Output is correct |
17 |
Correct |
600 ms |
65512 KB |
Output is correct |
18 |
Correct |
611 ms |
63992 KB |
Output is correct |
19 |
Correct |
637 ms |
64060 KB |
Output is correct |
20 |
Correct |
688 ms |
64192 KB |
Output is correct |
21 |
Correct |
710 ms |
64248 KB |
Output is correct |
22 |
Correct |
629 ms |
63992 KB |
Output is correct |
23 |
Correct |
574 ms |
65600 KB |
Output is correct |
24 |
Correct |
544 ms |
64248 KB |
Output is correct |
25 |
Correct |
571 ms |
63996 KB |
Output is correct |
26 |
Correct |
583 ms |
63992 KB |
Output is correct |
27 |
Correct |
650 ms |
64120 KB |
Output is correct |
28 |
Correct |
624 ms |
65784 KB |
Output is correct |
29 |
Correct |
633 ms |
65636 KB |
Output is correct |
30 |
Correct |
606 ms |
65708 KB |
Output is correct |
31 |
Correct |
628 ms |
65680 KB |
Output is correct |
32 |
Correct |
634 ms |
63964 KB |
Output is correct |
33 |
Correct |
680 ms |
64100 KB |
Output is correct |
34 |
Correct |
502 ms |
46328 KB |
Output is correct |
35 |
Correct |
695 ms |
65640 KB |
Output is correct |
36 |
Correct |
686 ms |
64248 KB |
Output is correct |
37 |
Correct |
733 ms |
65080 KB |
Output is correct |
38 |
Correct |
713 ms |
64504 KB |
Output is correct |
39 |
Correct |
663 ms |
68728 KB |
Output is correct |
40 |
Correct |
807 ms |
69496 KB |
Output is correct |
41 |
Correct |
661 ms |
64632 KB |
Output is correct |
42 |
Correct |
614 ms |
64324 KB |
Output is correct |
43 |
Correct |
745 ms |
68708 KB |
Output is correct |
44 |
Correct |
683 ms |
65096 KB |
Output is correct |
45 |
Correct |
623 ms |
69252 KB |
Output is correct |
46 |
Correct |
609 ms |
68856 KB |
Output is correct |
47 |
Correct |
613 ms |
65884 KB |
Output is correct |
48 |
Correct |
610 ms |
65784 KB |
Output is correct |
49 |
Correct |
615 ms |
66040 KB |
Output is correct |
50 |
Correct |
624 ms |
65528 KB |
Output is correct |
51 |
Correct |
778 ms |
69760 KB |
Output is correct |
52 |
Correct |
786 ms |
69904 KB |
Output is correct |