답안 #1009382

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1009382 2024-06-27T12:48:32 Z Muaath_5 늑대인간 (IOI18_werewolf) C++17
0 / 100
680 ms 292556 KB
#include "werewolf.h"
using namespace std;
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define ll long long
#define pii pair<int, int>
using namespace std;

const int N = 1<<20, LG = 21;

class reachability {
public:
	int sz;
	int dsu[N], par[N];
	vector<int> adj[N];
	reachability(){}
	reachability(int n) {
		sz = n;
		for (int i = 1; i <= n; i++)
			dsu[i] = par[i] = i;
	}
	
	int root(int x) {
		return x == dsu[x] ? x : dsu[x] = root(dsu[x]);
	}
	bool connect(int u, int v) {
		u = root(u), v = root(v);
		if (u == v) return false;
		sz++;
		dsu[u] = dsu[v] = dsu[sz] = sz;
		par[u] = par[v] = par[sz] = sz;
		adj[sz].push_back(u);
		adj[sz].push_back(v); 
		return true;
	}

	
	int jmp[N][LG];
	int dt[N], ft[N];
	int _time;
	int block[N];
	void dfsTree() {
		_time = 1;
		for (int i = sz; i >= 1; i--)
			if (!dt[i])
				dfs(i);
	}
	void dfs(int node) {
		dt[node] = _time++;
		for (int ch : adj[node])
			dfs(ch);
		ft[node] = _time;
	}
    void buildSt() {
        for (int i = 1; i <= sz; i++)
			jmp[i][0] = par[i];
		for (int j = 1; j < LG; j++) {
			for (int i = 1; i <= sz; i++) {
				jmp[i][j] = jmp[jmp[i][j-1]][j-1];
			}
		}
    }
	

	void cut() {
		block[sz] = 1;
		sz--;
	}
	
	int findComp(int u) {
		for (int i = LG-1; i >= 0; i--) {
			if (!block[jmp[u][i]]) {
				u = jmp[u][i];
			}
		}
		return u;
	}
};

#define OUT 0ll
int merge(int x, int y) { return x + y; }
 
static int R = 1 << 19, C = 1 << 19;
 
struct ynode {
    int val = OUT;
    ynode *left = nullptr, *right = nullptr;
};
 
struct xnode {
    xnode *left, *right;
    ynode *yy;
};
 
ll query_y(const int& qy1, const int& qy2, ynode* node, int l = 0, int r = C - 1)
{
    if (node == nullptr || r < qy1 || qy2 < l) return OUT;
    if (qy1 <= l && r <= qy2) return node->val;
    const int mid = (l + r) / 2;
    return merge(
        query_y(qy1, qy2, node->left, l, mid),
        query_y(qy1, qy2, node->right, mid + 1, r)
    );
}
 
ll query_x(const int& qx1, const int& qy1, const int& qx2, const int& qy2, xnode* node, int l = 0, int r = R - 1)
{
    if (node == nullptr || r < qx1 || qx2 < l) return OUT;
    if (qx1 <= l && r <= qx2) return query_y(qy1, qy2, node->yy);
    const int mid = (l + r) / 2;
    
    return merge(
        query_x(qx1, qy1, qx2, qy2, node->left, l, mid),
        query_x(qx1, qy1, qx2, qy2, node->right, mid + 1, r)
    );
}
 
 
void update_y(const int& qy, const int& val, ynode* node, int l = 0, int r = C - 1)
{
    if (l == r) {
        node->val = val;
        return;
    }
    const int mid = (l + r) / 2;
    if (qy <= mid) {
        if (!node->left) node->left = new ynode();
        update_y(qy, val, node->left, l, mid);
    }
    else {
        if (!node->right) node->right = new ynode();
        update_y(qy, val, node->right, mid + 1, r);
    }
    ll m1 = OUT, m2 = OUT;
    if (node->left) m1 = node->left->val;
    if (node->right) m2 = node->right->val;
    node->val = merge(m1, m2);
}
 
void update_x(const int& qx, const int& qy, const ll& val, xnode* node, int l = 0, int r = R - 1)
{
    if (!node->yy) node->yy = new ynode();
    if (l == r) {
        update_y(qy, val, node->yy);
        return;
    }
    const int mid = (l + r) / 2;
    if (qx <= mid) {
        if (!node->left) node->left = new xnode();
        update_x(qx, qy, val, node->left, l, mid);
    }
    else {
        if (!node->right) node->right = new xnode();
        update_x(qx, qy, val, node->right, mid + 1, r);
    }
    update_y(qy, merge(
        (node->left && node->left->yy ? query_y(qy, qy, node->left->yy) : OUT),
        (node->right && node->right->yy ? query_y(qy, qy, node->right->yy) : OUT)
    ), node->yy);
}
 
 
xnode* root;
 
void init(int r, int c) { R = r, C = c, root = new xnode(); }
void update(int x, int y, int k) { update_x(x, y, k, root); }
int query(int x1, int y1, int x2, int y2) { return query_x(x1, y1, x2, y2, root); }

vector<int> check_validity(int N, vector<int> X, vector<int> Y, vector<int> S, vector<int> E, vector<int> L, vector<int> R)
{
    const int M = X.size(), Q = S.size();
    // asdf
    //asdf
    //asdf
    reachability a(N), b(N);
    for (int i = 0; i < M; i++) {
        a.connect(X[i], Y[i]);
    }
    for (int i = M-1; i >= 0; i--) {
        b.connect(X[i], Y[i]);
    }


    init(a.sz+1, b.sz+1);
    for (int i = 1; i <= N; i++)
        update(a.dt[i], b.dt[i], 1);
    vector<int> sol(Q);
    for (int i = 0; i < Q; i++) {
        int u = a.findComp(L[i]);
        int v = b.findComp(R[i]);
        sol[i] = query(a.dt[u], b.dt[v], a.ft[u]-1, b.dt[v]-1);
    }
    return sol;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 131 ms 262992 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 131 ms 262992 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 680 ms 292556 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 131 ms 262992 KB Output isn't correct
2 Halted 0 ms 0 KB -