#include "werewolf.h"
#include <bits/stdc++.h>
#define ll long long
#define ff first
#define ss second
#define pb push_back
#define menor 0
#define mayor 1
using namespace std;
int n, m, q;
int rep[200001][2];
vector<pair<int, int> >edjes;
vector<int>adj[200001];
vector<int>linea;
int position[200001];
const int raiz = 450;
vector<vector<int>>divisiones;
int findd(int u, short cual){
if(rep[u][cual] == u)return u;
return rep[u][cual] = findd(rep[u][cual], cual);
}
void joinn(int a, int b, short cual){
a = findd(a, cual);
b = findd(b, cual);
if(a == b)return ;
rep[a][cual] = b;
}
void bfs(int u){
queue<int>cola;
cola.push(u);
while(!cola.empty()){
int cur = cola.front();
cola.pop();
linea.pb(cur);
position[cur] = linea.size()-1;
for(auto i : adj[cur]){
if(linea.size() >= 2 and linea[linea.size()-2] == i)continue;
cola.push(i);
}
}
}
struct segTree{
int minimo, maximo;
int dd, ht, mid;
segTree *L, *R;
segTree(int l, int r){
dd = l;
ht = r;
mid = (dd + ht)/2;
if(dd != ht){
L = new segTree(l, mid);
R = new segTree(mid + 1 , r);
minimo = min(L->minimo, R->minimo);
maximo = max(L->maximo, R->maximo);
}else{
minimo = linea[l];
maximo = linea[l];
}
}
int query(int l, int r, bool cual){
if ( dd == l and ht == r){
if( cual == mayor) return maximo;
return minimo;
}
if(r <= mid){
return L->query(l, r, cual);
}else if(l > mid){
return R->query(l, r, cual);
}else{
if(cual == mayor){
return max(L->query(l, mid, cual), R->query(mid+1, r, cual));
}else{
return min(L->query(l, mid, cual), R->query(mid+1, r, cual));
}
}
}
};
segTree *st;
int ver(int s, int pos, bool alreves){
if(!alreves){
int maximo = st->query(position[s], position[s] + pos, mayor);
//cout << " query max " << position[s] << " to " << position[s]+pos << " = " << maximo << endl;
return maximo;
}else{
int maximo = st->query(position[s] - pos, position[s], mayor);
//cout << " query max " << position[s] - pos << " to " << position[s] << " = " << maximo << endl;
return maximo;
}
}
bool buscar(int desde,int hasta, int l, int r){
if(desde > hasta)return false;
while(desde % raiz != 0 and desde <= hasta){
if(linea[desde] >= l and linea[desde] <= r)return true;
desde ++ ;
}
while((hasta % raiz) !=0 and hasta >= desde){
if(linea[hasta] >= l and linea[hasta] <= r)return true;
hasta -- ;
}
if(linea[hasta] >= l and linea[hasta] <= r)return true;
hasta --;
for(int i = desde / raiz ; i <= hasta/raiz ; i ++){
int k = *lower_bound(divisiones[i].begin(), divisiones[i].end(), l);
if( k >= l and k <= r)return true;
}
return false;
}
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) {
n = N;
m = X.size();
q = S.size();
int cuenta[N];
for(int i = 0 ; i < n ; i ++)cuenta[i] = 0;
for(int i = 0 ; i < m ; i ++){
edjes.pb({X[i], Y[i]});
cuenta[X[i]] ++;
cuenta[Y[i]] ++;
}
bool caso = true;
for(int i = 0 ; i < N ; i ++){
if(cuenta[i] > 2)caso = false;
}
vector<int>A;
if(!caso){
for(int query = 0 ; query < q ; query ++){
for(int i = 0 ; i < n ; i ++){
rep[i][0] = i;
rep[i][1] = i;
}
for(int i = 0 ; i < m ; i ++){
if(X[i] <= R[query] and Y[i] <= R[query]){
joinn(X[i], Y[i], 0);
}
if(X[i] >= L[query] and Y[i] >= L[query]){
joinn(X[i], Y[i], 1);
}
}
bool posible = false;
S[query] = findd(S[query], 1);
E[query] = findd(E[query], 0);
for(int i = L[query] ; i <= R[query] ; i ++){
if(findd(i, 1) == S[query] and findd(i, 0) == E[query]){
posible = true;
break;
}
}
if(posible)A.pb(1);
else A.pb(0);
}
}else{ // es una linea
int comienzo;
for(int i = 0 ; i < N ; i ++){
if(cuenta[i] == 1){
comienzo = i;
break;
}
}
for(int i = 0 ; i < m ; i ++){
adj[X[i]].pb(Y[i]);
adj[Y[i]].pb(X[i]);
}
bfs(comienzo);
st = new segTree(0, N-1);
int ii = 0;
vector<int>temporal;
while( ii < n){
temporal.pb(linea[ii]);
ii++;
if(ii%raiz == 0){
sort(temporal.begin(), temporal.end());
divisiones.pb(temporal);
temporal.clear();
}
}
for(int query = 0 ; query < q ; query++){
//cout << "query " << query << endl;
int s = S[query], e = E[query];
int mult = 1;
bool alreves = false;
if(position[s] > position[e]){
mult = -1;
alreves = true;
}
int li = 0, ls = max(position[s], position[e]) - min(position[s], position[e]) , pos;
//cout << "searching from " << li << " to " << ls << " alreves = " << alreves << endl;
pos = (li + ls)/2;
while(li+1 < ls){
//cout << "asking " << pos << endl;
int res = ver(e, pos, !alreves);
if(res > R[query]){
ls = pos;
}else{
li = pos+1;
}
pos = (li + ls)/2;
}
int ultimo;
if(ver(e, li, !alreves) > R[query]) ultimo = li;
else if(ver(e, ls, !alreves) > R[query]) ultimo = ls;
else ultimo = -1;
if(ultimo != -1)ultimo = max(position[s], position[e]) - min(position[s], position[e])-ultimo;
/*
if(ultimo != -1){
ultimo = max(position[s], position[e]) - min(position[s], position[e])-ultimo;
cout << "ultimo " << ultimo << endl;
if(!alreves && (position[s]+1 > position[s] + ultimo - 1 or st->query(position[s]+1, position[s]+ultimo-1, menor) >= L[query])){
}else if(alreves && (position[s] - ultimo + 1 > position[s]-1 or st->query(position[s] - ultimo+1, position[s]-1, menor) >= L[query])){
}else{
A.pb(0);
continue;
}
}
* */
//cout << "es valido " << query << endl;
//cout << position[s] << " " << ultimo << endl;
li = 1, ls = max(position[s], position[e]) - min(position[s], position[e]) , pos;
//cout << "searching from " << li << " to " << ls << " alreves = " << alreves << endl;
pos = (li + ls)/2;
while(li+1 < ls){
//cout << "asking " << pos << endl;
int res = ver(s, pos, alreves);
if(res < L[query]){
ls = pos;
}else{
li = pos+1;
}
pos = (li + ls)/2;
}
int ultimo2 = -1;
if(ver(s, li, alreves) < L[query]) ultimo2 = li;
else if(ver(s, ls, alreves) < L[query]) ultimo2 = ls;
else ultimo2 = -1;
int desde, hasta;
if(!alreves){
desde = position[s] + ultimo + 1;
hasta = position[s] + ultimo2 - 1;
if(ultimo == -1){
desde = position[s];
}
if(ultimo2 ==-1){
hasta = position[e];
}
}else{
hasta = position[s] - ultimo - 1;
desde = position[s] - ultimo2 + 1;
if(ultimo == -1){
hasta = position[s];
}
if(ultimo2 ==-1){
desde = position[e];
}
}
bool ans = buscar(desde, hasta, L[query], R[query]);
//cout << "encontrado " << ans << endl;
if(ans)A.pb(1);
else A.pb(0);
}
}
return A;
}
Compilation message
werewolf.cpp: In function 'std::vector<int> check_validity(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
werewolf.cpp:233:86: warning: right operand of comma operator has no effect [-Wunused-value]
233 | li = 1, ls = max(position[s], position[e]) - min(position[s], position[e]) , pos;
| ^
werewolf.cpp:193:10: warning: variable 'mult' set but not used [-Wunused-but-set-variable]
193 | int mult = 1;
| ^~~~
werewolf.cpp:175:8: warning: 'comienzo' may be used uninitialized in this function [-Wmaybe-uninitialized]
175 | bfs(comienzo);
| ~~~^~~~~~~~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
4 ms |
4948 KB |
Output is correct |
2 |
Correct |
3 ms |
4948 KB |
Output is correct |
3 |
Correct |
3 ms |
5004 KB |
Output is correct |
4 |
Correct |
2 ms |
4948 KB |
Output is correct |
5 |
Correct |
3 ms |
4948 KB |
Output is correct |
6 |
Correct |
3 ms |
5012 KB |
Output is correct |
7 |
Correct |
3 ms |
4948 KB |
Output is correct |
8 |
Runtime error |
7 ms |
9960 KB |
Execution killed with signal 11 |
9 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
4 ms |
4948 KB |
Output is correct |
2 |
Correct |
3 ms |
4948 KB |
Output is correct |
3 |
Correct |
3 ms |
5004 KB |
Output is correct |
4 |
Correct |
2 ms |
4948 KB |
Output is correct |
5 |
Correct |
3 ms |
4948 KB |
Output is correct |
6 |
Correct |
3 ms |
5012 KB |
Output is correct |
7 |
Correct |
3 ms |
4948 KB |
Output is correct |
8 |
Runtime error |
7 ms |
9960 KB |
Execution killed with signal 11 |
9 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Runtime error |
261 ms |
98000 KB |
Execution killed with signal 11 |
2 |
Halted |
0 ms |
0 KB |
- |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
4 ms |
4948 KB |
Output is correct |
2 |
Correct |
3 ms |
4948 KB |
Output is correct |
3 |
Correct |
3 ms |
5004 KB |
Output is correct |
4 |
Correct |
2 ms |
4948 KB |
Output is correct |
5 |
Correct |
3 ms |
4948 KB |
Output is correct |
6 |
Correct |
3 ms |
5012 KB |
Output is correct |
7 |
Correct |
3 ms |
4948 KB |
Output is correct |
8 |
Runtime error |
7 ms |
9960 KB |
Execution killed with signal 11 |
9 |
Halted |
0 ms |
0 KB |
- |