// moreflags=grader.cpp
#include "werewolf.h"
#include<vector>
#include<set>
#include<climits>
#include<algorithm>
#if not LOCAL
#define NDEBUG
#endif
#include<cassert>
struct Dsu{ // with path compression but without union by rank
std::vector<int> data; // positive: parent, negative: ~(minimum in component)
Dsu(int number): data(number){
for(int node=0; node<number; ++node)
data[node]=~ node;
}
int root(int node){return data[node]>=0 ? data[node]=root(data[node]): node;}
int minimumInComponent(int node){
return ~data[root(node)];
}
bool join(int first, int sec){
first=root(first); sec=root(sec);
if(first==sec) return false;
data[first]=std::max(data[first], data[sec]); // inverted
data[sec]=first;
return true;
}
};
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) {
std::vector<std::vector<int>> greaterAdd(N), lessAdd(N);
for(int index=0; index<(int)X.size(); ++index){
auto const [a, b]=std::minmax({X[index], Y[index]});
assert(a!=b);
greaterAdd[a].push_back(b);
lessAdd[N-1-b].push_back(N-1-a);
}
auto const process=[&](std::vector<std::vector<int>>& add)->std::vector<int>{
// add: adjacency list (elements of list [i] must be strictly greater than i)
// also reuse add for the children of the resulting par
// (node n is for -1)
std::vector<int> par(add.size(), -1);
Dsu dsu((int)add.size());
for(auto index=(int)add.size(); index--;){
for(auto other: add[index]){
other=dsu.minimumInComponent(other);
if(other>index){
auto const success=dsu.join(index, other);
assert(success);
assert(par[other]==-1);
par[other]=index;
}else assert(other==index);
}
}
for(auto& it: add) it.clear();
add.emplace_back();
for(int node=0; node<(int)par.size(); ++node){
(par[node]<0 ? add.back(): add[par[node]]).push_back(node);
}
return par;
};
std::vector<int> greaterPar=process(greaterAdd);
std::vector<int> lessPar=process(lessAdd);
// greaterPar: the equivalent structure of traversing with the additional condition (vertex >= L)
// for some L
// ( i -> greaterPar[i] ) where greaterPar[i]<i
// lessPar: vice versa, but with flipped vertex indices
struct Jump{
std::vector<std::vector<int>> data;
// assumes -1 is the virtual root
Jump(std::vector<int> value): data{std::move(value)}{
for(int step=1; step<(int)data.back().size(); step<<=1){
std::vector<int> const& a=data.back();
auto b=a;
bool useful=false;
for(auto& it: b) if(it>=0){
it=a[it];
if(it>=0) useful=true;
}
if(useful)
data.push_back(std::move(b));
else break;
}
}
int get(int node, int least)const{
// assumes par[node]<node for all node, find minimum ancestor >=least
for(auto layer=data.size(); layer--;)
if(data[layer][node]>=least) node=data[layer][node];
return node;
}
};
Jump greaterJump(std::move(greaterPar)), lessJump(std::move(lessPar));
struct Query{int node, index;};
std::vector<std::vector<Query>> queries(N);
// [node1] = (node2, query): query with index==query -> greater subtree rooted at node1
// has any common vertex with less subtree rooted at node2?
for(int query=0; query<(int)S.size(); ++query){
int node1=greaterJump.get(S[query], L[query]);
int node2=lessJump.get(N-1-E[query], N-1-R[query]);
queries[node1].push_back({node2, query});
}
std::vector<int> result(S.size());
// solve all queries
/* // * not necessary
auto const subtreeSize=[&]{ // of greater
std::vector<int> result(N);
auto const work=[&](auto work, int node)->int{
auto cur=1;
for(auto other: greaterAdd[node])
cur+=work(work, other);
return result[node]=cur;
};
for(auto it: greaterAdd[N]) work(work, it);
for(auto it: result) assert(it>0);
return result;
}();
*/
auto const merge=[&](std::set<int> first, std::set<int> sec){
if(first.size()<sec.size()) std::swap(first, sec);
for(auto it: sec){
auto const success=first.insert(it).second;
assert(success);
}
return first;
};
std::vector<int> lessFirst(N), lessLast(N); // first and last index in preorder traversal of the less tree
{ // construct ^
int cur=0;
auto const work=[&](auto work, int node)->void{
assert(lessFirst[node]==0);
lessFirst[node]=cur++;
for(auto other: lessAdd[node])
work(work, other);
lessLast[node]=cur;
};
for(auto node: lessAdd[N]){
work(work, node);
}
assert(cur==N);
}
// wait it's not necessary to compute subtreeSize if std::set is used anyway
auto const work=[&](auto work, int node)->std::set<int>{
std::set<int> curSet{lessFirst[N-1-node]};
for(auto other: greaterAdd[node])
curSet=merge(std::move(curSet), work(work, other));
for(auto [node2, queryIndex]: queries[node]){
auto const iterator=curSet.lower_bound(lessFirst[node2]);
if(iterator!=curSet.end() and *iterator<lessLast[node2])
result[queryIndex]=1;
}
return curSet;
};
for(auto it: greaterAdd[N]) work(work, it);
return result;
}
Compilation message
werewolf.cpp: In lambda function:
werewolf.cpp:53:17: warning: unused variable 'success' [-Wunused-variable]
53 | auto const success=dsu.join(index, other);
| ^~~~~~~
werewolf.cpp: In lambda function:
werewolf.cpp:137:15: warning: unused variable 'success' [-Wunused-variable]
137 | auto const success=first.insert(it).second;
| ^~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
384 KB |
Output is correct |
2 |
Correct |
1 ms |
384 KB |
Output is correct |
3 |
Correct |
1 ms |
384 KB |
Output is correct |
4 |
Correct |
1 ms |
256 KB |
Output is correct |
5 |
Correct |
1 ms |
384 KB |
Output is correct |
6 |
Correct |
1 ms |
384 KB |
Output is correct |
7 |
Correct |
1 ms |
384 KB |
Output is correct |
8 |
Correct |
1 ms |
384 KB |
Output is correct |
9 |
Correct |
1 ms |
384 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
384 KB |
Output is correct |
2 |
Correct |
1 ms |
384 KB |
Output is correct |
3 |
Correct |
1 ms |
384 KB |
Output is correct |
4 |
Correct |
1 ms |
256 KB |
Output is correct |
5 |
Correct |
1 ms |
384 KB |
Output is correct |
6 |
Correct |
1 ms |
384 KB |
Output is correct |
7 |
Correct |
1 ms |
384 KB |
Output is correct |
8 |
Correct |
1 ms |
384 KB |
Output is correct |
9 |
Correct |
1 ms |
384 KB |
Output is correct |
10 |
Correct |
8 ms |
1536 KB |
Output is correct |
11 |
Correct |
7 ms |
1408 KB |
Output is correct |
12 |
Correct |
7 ms |
1152 KB |
Output is correct |
13 |
Correct |
8 ms |
1536 KB |
Output is correct |
14 |
Correct |
10 ms |
1536 KB |
Output is correct |
15 |
Correct |
9 ms |
1536 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
925 ms |
58536 KB |
Output is correct |
2 |
Correct |
1120 ms |
86568 KB |
Output is correct |
3 |
Correct |
984 ms |
77096 KB |
Output is correct |
4 |
Correct |
918 ms |
71588 KB |
Output is correct |
5 |
Correct |
929 ms |
69864 KB |
Output is correct |
6 |
Correct |
963 ms |
71844 KB |
Output is correct |
7 |
Correct |
842 ms |
67748 KB |
Output is correct |
8 |
Correct |
1084 ms |
86568 KB |
Output is correct |
9 |
Correct |
777 ms |
76496 KB |
Output is correct |
10 |
Correct |
714 ms |
70700 KB |
Output is correct |
11 |
Correct |
739 ms |
69796 KB |
Output is correct |
12 |
Correct |
793 ms |
68844 KB |
Output is correct |
13 |
Correct |
1252 ms |
124456 KB |
Output is correct |
14 |
Correct |
1214 ms |
124268 KB |
Output is correct |
15 |
Correct |
1216 ms |
124528 KB |
Output is correct |
16 |
Correct |
1232 ms |
124520 KB |
Output is correct |
17 |
Correct |
845 ms |
67880 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
384 KB |
Output is correct |
2 |
Correct |
1 ms |
384 KB |
Output is correct |
3 |
Correct |
1 ms |
384 KB |
Output is correct |
4 |
Correct |
1 ms |
256 KB |
Output is correct |
5 |
Correct |
1 ms |
384 KB |
Output is correct |
6 |
Correct |
1 ms |
384 KB |
Output is correct |
7 |
Correct |
1 ms |
384 KB |
Output is correct |
8 |
Correct |
1 ms |
384 KB |
Output is correct |
9 |
Correct |
1 ms |
384 KB |
Output is correct |
10 |
Correct |
8 ms |
1536 KB |
Output is correct |
11 |
Correct |
7 ms |
1408 KB |
Output is correct |
12 |
Correct |
7 ms |
1152 KB |
Output is correct |
13 |
Correct |
8 ms |
1536 KB |
Output is correct |
14 |
Correct |
10 ms |
1536 KB |
Output is correct |
15 |
Correct |
9 ms |
1536 KB |
Output is correct |
16 |
Correct |
925 ms |
58536 KB |
Output is correct |
17 |
Correct |
1120 ms |
86568 KB |
Output is correct |
18 |
Correct |
984 ms |
77096 KB |
Output is correct |
19 |
Correct |
918 ms |
71588 KB |
Output is correct |
20 |
Correct |
929 ms |
69864 KB |
Output is correct |
21 |
Correct |
963 ms |
71844 KB |
Output is correct |
22 |
Correct |
842 ms |
67748 KB |
Output is correct |
23 |
Correct |
1084 ms |
86568 KB |
Output is correct |
24 |
Correct |
777 ms |
76496 KB |
Output is correct |
25 |
Correct |
714 ms |
70700 KB |
Output is correct |
26 |
Correct |
739 ms |
69796 KB |
Output is correct |
27 |
Correct |
793 ms |
68844 KB |
Output is correct |
28 |
Correct |
1252 ms |
124456 KB |
Output is correct |
29 |
Correct |
1214 ms |
124268 KB |
Output is correct |
30 |
Correct |
1216 ms |
124528 KB |
Output is correct |
31 |
Correct |
1232 ms |
124520 KB |
Output is correct |
32 |
Correct |
845 ms |
67880 KB |
Output is correct |
33 |
Correct |
1193 ms |
83240 KB |
Output is correct |
34 |
Correct |
395 ms |
32888 KB |
Output is correct |
35 |
Correct |
1339 ms |
100432 KB |
Output is correct |
36 |
Correct |
1154 ms |
81580 KB |
Output is correct |
37 |
Correct |
1308 ms |
96828 KB |
Output is correct |
38 |
Correct |
1212 ms |
86440 KB |
Output is correct |
39 |
Correct |
1234 ms |
95600 KB |
Output is correct |
40 |
Correct |
1170 ms |
105772 KB |
Output is correct |
41 |
Correct |
941 ms |
92840 KB |
Output is correct |
42 |
Correct |
792 ms |
79912 KB |
Output is correct |
43 |
Correct |
1367 ms |
115892 KB |
Output is correct |
44 |
Correct |
1079 ms |
95784 KB |
Output is correct |
45 |
Correct |
1052 ms |
96552 KB |
Output is correct |
46 |
Correct |
1112 ms |
93348 KB |
Output is correct |
47 |
Correct |
1244 ms |
124584 KB |
Output is correct |
48 |
Correct |
1242 ms |
124196 KB |
Output is correct |
49 |
Correct |
1218 ms |
124456 KB |
Output is correct |
50 |
Correct |
1216 ms |
124324 KB |
Output is correct |
51 |
Correct |
1020 ms |
106152 KB |
Output is correct |
52 |
Correct |
1004 ms |
105896 KB |
Output is correct |