이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#ifdef LOCAL
#else
#include <werewolf.h>
#endif
#include <bits/stdc++.h>
#define fi first
#define se second
#define pn printf("\n")
#define ssize(x) int(x.size())
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<int, ll> pli;
typedef double db;
typedef long double ldb;
struct st_query{
int s, e, l, r, i;
st_query(){}
st_query(int S, int E, int L, int R) : s(S), e(E), l(L), r(R) {}
};
struct DSU{
int c;
vector<int> rep;
void init(int n, int N){ c = N, rep = vector<int>(), rep.resize(n+1); for(int i = 1; i <= n; ++i) rep[i] = i; }
int Find(int x){
int b;
if(x != rep[x]) b = x, x = Find(rep[x]), rep[b] = x;
return x;
} void add_edge(int u, int v, vector<vector<int>> &g){
u = Find(u), v = Find(v);
if(u == v) return;
g[++c].emplace_back(u), g[c].emplace_back(v);
rep[u] = c, rep[v] = c;
}
} DSU;
void dfs(int x, int &c, vector<vector<int>> &g, vector<pii> &preorder){
++c, preorder[x].fi = c;
for(int u : g[x]) dfs(u, c, g, preorder);
preorder[x].se = c;
} struct st_event{
int type; // 0 - poczatek -> query / 1 - punkt -> add / 2 - koniec -> query
int l, r, i;
st_event(){}
st_event(int L) : type(1), l(L) {}
st_event(int T, int L, int R, int I) : type(T), l(L), r(R), i(I) {}
bool operator <(const st_event &x) { return type < x.type; }
}; int base = 1;
struct seg{
vector<int> t;
void init(int n){
while(base < n) base <<= 1;
t.resize(base<<1);
} void add(int x){for(x += base-1; x; x >>= 1) ++t[x];}
int query(int i, int pocz, int kon, int x, int y){
if(x <= pocz && kon <= y) return t[i];
int sr = (pocz+kon)>>1, wynik = 0;
if(x <= sr) wynik += query(i<<1, pocz, sr, x, y);
if(sr < y) wynik += query(i<<1|1, sr+1, kon, x, y);
return wynik;
}
} seg;
#ifdef LOCAL
int main(){
int n, m, q, a, b; scanf("%d%d%d", &n, &m, &q);
vector<vector<int>> g_greater(n+1), g_smaller(n+1);
vector<st_query> v_query(q);
vector<vector<pii>> starts(n+1), ends(n+1);
for(int i = 0; i < m; ++i){
scanf("%d%d", &a, &b); ++a, ++b;
if(a > b) swap(a, b);
g_greater[a].emplace_back(b), g_smaller[b].emplace_back(a);
} for(int i = 0; i < q; ++i){
scanf("%d%d%d%d", &v_query[i].s, &v_query[i].e, &v_query[i].l, &v_query[i].r);
++v_query[i].s, ++v_query[i].e, ++v_query[i].l, ++v_query[i].r, v_query[i].i = i;
starts[v_query[i].l].emplace_back(v_query[i].s, i), ends[v_query[i].r].emplace_back(v_query[i].e, i);
} vector<vector<int>> gL(n+m+1), gR(n+m+1);
vector<int> query_nodes_L(q), query_nodes_R(q);
vector<pii> preorderL(n+m+1), preorderR(n+m+1);
//tworzenie pierwszego drzewa (dla L)
DSU.init(n+m, n);
for(int x = n-1; x; --x){
for(int u : g_greater[x]) DSU.add_edge(x, u, gL);
for(pii s : starts[x]) query_nodes_L[s.se] = DSU.Find(s.fi);
} int cnt = 0; dfs(DSU.c, cnt, gL, preorderL);
//tworzenie drugiego drzewa (dla R)
DSU.init(n+m, n);
for(int x = 2; x <= n; ++x){
for(int u : g_smaller[x]) DSU.add_edge(x, u, gR);
for(pii s : ends[x]) query_nodes_R[s.se] = DSU.Find(s.fi);
} cnt = 0; dfs(DSU.c, cnt, gR, preorderR);
//tworzenie zamiatania
seg.init(n+m+1);
vector<vector<st_event>> t(n+m+1);
for(int i = 0; i < q; ++i)
t[preorderL[query_nodes_L[i]].fi].emplace_back(0, preorderR[query_nodes_R[i]].fi, preorderR[query_nodes_R[i]].se, i),
t[preorderL[query_nodes_L[i]].se].emplace_back(2, preorderR[query_nodes_R[i]].fi, preorderR[query_nodes_R[i]].se, i);
for(int i = 1; i <= n; ++i) t[preorderL[i].fi].emplace_back(preorderR[i].fi);
vector<int> wynik(q);
for(int i = 1; i <= n+m; ++i){
sort(t[i].begin(), t[i].end());
for(st_event u : t[i]){
if(!u.type) wynik[u.i] = seg.query(1, 1, base, u.l, u.r);
else if(u.type == 2) wynik[u.i] = min(1, seg.query(1, 1, base, u.l, u.r) - wynik[u.i]);
else seg.add(u.l);
}
} for(int i : wynik) printf("%d\n", i);
return 0;
}
#else
vector<int> check_validity(int n, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R){
int m = ssize(X), q = ssize(S), a, b;
vector<vector<int>> g_greater(n+1), g_smaller(n+1);
vector<st_query> v_query(q);
vector<vector<pii>> starts(n+1), ends(n+1);
for(int i = 0; i < m; ++i){
a = X[i], b = Y[i], ++a, ++b;
if(a > b) swap(a, b);
g_greater[a].emplace_back(b), g_smaller[b].emplace_back(a);
} for(int i = 0; i < q; ++i){
v_query[i].s = S[i], v_query[i].e = E[i], v_query[i].l = L[i], v_query[i].r = R[i];
++v_query[i].s, ++v_query[i].e, ++v_query[i].l, ++v_query[i].r, v_query[i].i = i;
starts[v_query[i].l].emplace_back(v_query[i].s, i), ends[v_query[i].r].emplace_back(v_query[i].e, i);
} vector<vector<int>> gL(n+m+1), gR(n+m+1);
vector<int> query_nodes_L(q), query_nodes_R(q);
vector<pii> preorderL(n+m+1), preorderR(n+m+1);
//tworzenie pierwszego drzewa (dla L)
DSU.init(n+m, n);
for(int x = n-1; x; --x){
for(int u : g_greater[x]) DSU.add_edge(x, u, gL);
for(pii s : starts[x]) query_nodes_L[s.se] = DSU.Find(s.fi);
} int cnt = 0; dfs(DSU.c, cnt, gL, preorderL);
//tworzenie drugiego drzewa (dla R)
DSU.init(n+m, n);
for(int x = 2; x <= n; ++x){
for(int u : g_smaller[x]) DSU.add_edge(x, u, gR);
for(pii s : ends[x]) query_nodes_R[s.se] = DSU.Find(s.fi);
} cnt = 0; dfs(DSU.c, cnt, gR, preorderR);
//tworzenie zamiatania
seg.init(n+m+1);
vector<vector<st_event>> t(n+m+1);
for(int i = 0; i < q; ++i)
t[preorderL[query_nodes_L[i]].fi].emplace_back(0, preorderR[query_nodes_R[i]].fi, preorderR[query_nodes_R[i]].se, i),
t[preorderL[query_nodes_L[i]].se].emplace_back(2, preorderR[query_nodes_R[i]].fi, preorderR[query_nodes_R[i]].se, i);
for(int i = 1; i <= n; ++i) t[preorderL[i].fi].emplace_back(preorderR[i].fi);
vector<int> wynik(q);
for(int i = 1; i <= n+m; ++i){
sort(t[i].begin(), t[i].end());
for(st_event u : t[i]){
if(!u.type) wynik[u.i] = seg.query(1, 1, base, u.l, u.r);
else if(u.type == 2) wynik[u.i] = min(1, seg.query(1, 1, base, u.l, u.r) - wynik[u.i]);
else seg.add(u.l);
}
}
return wynik;
}
#endif
# | 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... |