#include<bits/stdc++.h>
#define fi first
#define se second
#define all(v) begin(v), end(v)
#define rall(v) rbegin(v), rend(v)
#define compact(v) v.erase(unique(all(v)), end(v))
#define sz(v) (int)(v).size()
#define vi vector<int>
#define pii pair<int,int>
#define endl "\n"
#define dbg(x) "[" #x " = " << (x) << "]"
using namespace std;
template<class T> bool minimize(T& a, T b){
    if(a > b) return a = b, true;
    return false;
}
template<class T> bool maximize(T& a, T b){
    if(a < b) return a = b, true;
    return false;
}
typedef long long ll;
const int N = 1e6 + 15;
int n, m, q;
int eu[N], ev[N];
struct dsu_tree{
    int n, timerDFS = 0;
    vi lab, tin, tout;
    vector<vi> g;
    dsu_tree(int n) : n(n), lab(n << 1 | 1, -1), g(n << 1 | 1),  tin(n << 1 | 1,0), tout(n << 1 | 1,0) {}
    int asc(int u){
        return lab[u] < 0 ? u : lab[u] = asc(lab[u]);
    }
    void join(int u, int v){
        u = asc(u), v = asc(v);
        if(u == v) return;
        lab[u] = lab[v] = ++n;
        //cout << n << " " << u << endl;
        //cout << n << " " << v << endl;
        g[n].push_back(u), g[n].push_back(v);
    }
    bool inside(int u, int v){
        return tin[u] <= tin[v] && tout[v] <= tout[u];
    }
    void dfs(int u){
        tin[u] = ++timerDFS;
        for(int v : g[u]){
            dfs(v);
        }
        tout[u] = timerDFS;
    }
};
vector<int> queryDown[N], queryUp[N];
int bigU[N], bigV[N];
int bit[N];
vector<int> g[N];
void update(int idx, int v){
    for(;idx <= 2*n; idx += (idx & -idx)) bit[idx] += v;
}
int get(int idx){
    int res = 0;
    for(; idx; idx -= (idx & -idx)){
        assert(idx >= 0);
        res += bit[idx];
    }
    return res;
}
vi check_validity(int _N, vi X, vi Y, vi U, vi V, vi _L, vi _R){
    n = _N;
    m = sz(X);
    q = sz(U);
    for(int i = 1; i <= m; i++){
        tie(eu[i], ev[i]) = {X[i-1], Y[i-1]};
        eu[i]++, ev[i]++;
        g[eu[i]].push_back(ev[i]);
        g[ev[i]].push_back(eu[i]);
    }
    for(int i = 0; i < q; i++){
        _L[i]++, _R[i]++, U[i]++, V[i]++;
        queryDown[_R[i]].emplace_back(i);
        queryUp[_L[i]].emplace_back(i);
    }
    dsu_tree krt1(n), krt2(n);
    for(int i = 1; i <= n; i++){
        for(int v : g[i]){
            if(v > i) continue;
            krt1.join(i, v);
        }
        for(int id : queryDown[i]){
            bigV[id] = krt1.asc(V[id]);
        }
    }
    for(int i = n; i >= 1; i--){
        for(int v : g[i]){
            if(v < i) continue;
            krt2.join(i, v);
        }
        for(int id : queryUp[i]){
            bigU[id] = krt2.asc(U[id]);
        }
    }
    krt1.dfs(2*n - 1);
    krt2.dfs(2*n - 1);
    vector<pii> point;
    vector<pair<pii, int>> query;
    vector<int> ans(q, 0);
    for(int i = 1; i <= n; i++){
        point.emplace_back(krt2.tin[i], krt1.tin[i]);
    }
    for(int i = 0; i < q; i++){
        int x1, x2; tie(x1, x2) = {krt2.tin[bigU[i]], krt2.tout[bigU[i]]};
        int y1, y2; tie(y1, y2) = {krt1.tin[bigV[i]], krt1.tout[bigV[i]]};
        query.push_back({{x2, y2}, +(i+1)});
        if(x1 - 1) query.push_back({{x1 - 1, y2}, -(i+1)});
        if(y1 - 1) query.push_back({{x2, y1 - 1}, -(i+1)});
        if(x1 - 1 && y1 - 1) query.push_back({{x1 - 1, y1 - 1}, +(i+1)});
    }
    sort(all(point));
    sort(all(query), [&](auto a, auto b){
        return a.fi.fi < b.fi.fi;
    });
    for(int i = 0, j = 0; i < sz(query); i++){
        while(j < sz(point) && point[j].fi <= query[i].fi.fi){
            update(point[j].se, 1);
            j++;
        }
        int id = query[i].se;
        int sign = (id < 0) ? -1 : 1;
        id *= sign;
        id--;
        ans[id] += sign*get(query[i].fi.se);
    }
    for(int i = 0; i < sz(ans); i++) if(ans[i]) ans[i] = 1;
    return ans;
}
#ifdef LOCAL
void fastIO(){
    ios_base::sync_with_stdio(NULL); cin.tie(0);
    freopen("task.INP", "r", stdin);
    freopen("task.OUT", "w", stdout);
}
signed main(){
    fastIO();
    vector<int> res = check_validity(6, {5, 1, 1, 3, 3, 5}, {1, 2, 3, 4, 0, 2},
{4, 4, 5}, {2, 2, 4}, {1, 2, 3}, {2, 2, 4});
}
#endif
//check_validity(6, {5, 1, 1, 3, 3, 5}, {1, 2, 3, 4, 0, 2},
//{4, 4, 5}, {2, 2, 4}, {1, 2, 3}, {2, 2, 4});
| # | 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... |