This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include "werewolf.h"
#include <bits/stdc++.h>
#define eb emplace_back
#define sz(V) ((int)(V).size())
#define allv(V) ((V).begin()),((V).end())
#define sorv(V) sort(allv(V))
#define rb(x) ((x)&(-(x)))
using namespace std;
const int MAXN = 200055;
const int MAXM = 400055;
const int MAXQ = 200055;
struct TRE {
vector<int> G[MAXN];
int prt[18][MAXN], cnt[MAXN], dfo[MAXN];
int N, Rt;
void add(int p, int v) { G[p].eb(v); }
void dfs(int i, int &c) {
cnt[i] = 1; dfo[i] = c++;
for(int v : G[i]) {
prt[0][v] = i;
dfs(v, c);
cnt[i] += cnt[v];
}
}
void run() {
prt[0][Rt] = N;
for(int i = 18; i--;) prt[i][N] = N;
{ int _ = 0; dfs(Rt, _); }
for(int j = 1; j < 18; j++) for(int i = 0; i < N; i++)
prt[j][i] = prt[j-1][prt[j-1][i]];
}
} TA, TB;
struct BIT {
int d[MAXN];
void upd(int x) {
for(x += 5; x < MAXN; x += rb(x)) d[x]++;
}
int get(int x) {
int r = 0; for(x += 5; x; x -= rb(x))
r += d[x];
return r;
}
} bit;
struct EVT {
EVT(int idx, int x, int y, bool inv)
: idx(idx), x(x), y(y), inv(inv) {}
int idx, x, y;
bool inv;
bool operator < (const EVT &t) const {
if(x != t.x) return x < t.x;
return idx < t.idx;
}
};
vector<EVT> EV;
vector<int> G[MAXN];
int ud[MAXN];
int A[MAXM], B[MAXM];
int CS[MAXQ], CE[MAXQ], L[MAXQ], R[MAXQ];
int Ans[MAXQ];
int N, M, Q;
int uf(int i) { return i == ud[i] ? i : (ud[i] = uf(ud[i])); }
void uf(int a, int b) { ud[uf(b)] = uf(a); }
int getMx(int v, int c) {
for(int i = 18, p; i--;) {
p = TA.prt[i][v];
if(p <= c) v = p;
}
return v;
}
int getMn(int v, int c) {
for(int i = 18, p; i--;) {
p = TB.prt[i][v];
if(c <= p && p < N) v = p;
}
return v;
}
void getAns() {
for(int i = 0, a, b; i < M; i++) {
a = A[i]; b = B[i];
G[a].eb(b); G[b].eb(a);
}
TA.N = TB.N = N; TA.Rt = N-1;
iota(ud, ud+N, 0);
for(int i = 1; i < N; i++) for(int v : G[i]) {
if(i < v) continue;
v = uf(v);
if(v != i) TA.add(i, v);
uf(i, v);
}
iota(ud, ud+N, 0);
for(int i = N; i--;) for(int v : G[i]) {
if(v < i) continue;
v = uf(v);
if(v != i) TB.add(i, uf(v));
uf(i, v);
}
TA.run(); TB.run();
for(int i = 0; i < N; i++)
EV.eb(-1, TA.dfo[i], TB.dfo[i], false);
for(int i = 0, a, b; i < Q; i++) {
a = getMx(CE[i], R[i]);
b = getMn(CS[i], L[i]);
EV.eb(i, TA.dfo[a]-1, TB.dfo[b]-1, true);
EV.eb(i, TA.dfo[a]-1, TB.dfo[b]+TB.cnt[b]-1, false);
a = TA.dfo[a]+TA.cnt[a]-1;
EV.eb(i, a, TB.dfo[b]-1, false);
EV.eb(i, a, TB.dfo[b]+TB.cnt[b]-1, true);
}
sorv(EV);
for(auto &ev : EV) {
if(ev.idx < 0) bit.upd(ev.y);
else Ans[ev.idx] += bit.get(ev.y) * (ev.inv ? -1 : 1);
}
}
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 = sz(X); ::Q = sz(S);
for(int i = 0; i < M; i++) { ::A[i] = X[i]; ::B[i] = Y[i]; }
for(int i = 0; i < Q; i++) {
::CS[i] = S[i]; ::CE[i] = E[i];
::L[i] = L[i]; ::R[i] = R[i];
}
getAns();
vector<int> V;
for(int i = 0; i < Q; i++) V.eb(!!Ans[i]);
return V;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |