답안 #1011331

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
1011331 2024-06-30T10:54:19 Z Muaath_5 늑대인간 (IOI18_werewolf) C++17
0 / 100
582 ms 228748 KB
#include "werewolf.h"
using namespace std;
#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define ll long long
#define chmax(x, y) x = max(x, y)
#define chmin(x, y) x = min(x, y)
#define pii pair<int, int>
using namespace std;

const int N = 1<<19, INF = 1e9, LG = 20;

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];
    // Maintain minimum/maximum in every subtree
    int mn[N], mx[N];
	void dfsTree() {
        fill(mx, mx+sz+1, -INF);
        fill(mn, mn+sz+1, +INF);
		_time = 1;
		dfs(sz);
	}
	void dfs(int node) {
		dt[node] = _time++;
        if (adj[node].size() == 0)
            mn[node] = mx[node] = node;
		for (int ch : adj[node]) {
			dfs(ch);
            chmin(mn[node], mn[ch]);
            chmax(mx[node], mx[ch]);
        }
		ft[node] = _time-1;
        
	}
    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 cutLastEdge() {
		block[sz] = 1;
		sz--;
	}
	
    int findCompLeqMx(int u, int lim) {
        for (int i = LG-1; i >= 0; i--) {
			if (mx[jmp[u][i]] <= lim) {
				u = jmp[u][i];
			}
		}
        return u;
    }

    int findCompGeqMn(int u, int lim) {
        for (int i = LG-1; i >= 0; i--) {
			if (mn[jmp[u][i]] >= lim) {
				u = jmp[u][i];
			}
		}
        return u;
    }

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


int tree[4*N];
void update(int idx, int l=0, int r=N-1, int node=1) {
	if (l == r) {
		tree[node]++;
		return;
	}
	const int mid = (l+r)/2;
	if (idx <= mid)
		update(idx, l, mid, node*2);
	else
		update(idx, mid+1, r, node*2+1);
	tree[node] = tree[node*2] + tree[node*2+1];
}

ll query(int ql, int qr, int l=0, int r=N-1, int node=1) {
	if (ql <= l && r <= qr) return tree[node];
	if (l > qr || r < ql) return 0;
	const int mid = (l+r)/2;
	return query(ql, qr, l, mid, node*2) + query(ql, qr, mid+1, r, node*2+1);
}

vector<int> adj[N];

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();
    for (int i = 0; i < M; i++)
        X[i]++, Y[i]++;
    for (int i = 0; i < Q; i++)
        S[i]++, E[i]++, L[i]++, R[i]++;

    for (int i = 0; i < M; i++)
        adj[X[i]].push_back(Y[i]),
        adj[Y[i]].push_back(X[i]);

    reachability human(N), werewolf(N);    
    for (int i = 1; i <= N; i++)
        for (int ch : adj[i])
            if (ch <= i)
                werewolf.connect(i, ch);

    for (int i = N; i >= 1; i--)
        for (int ch : adj[i])
            if (ch >= i)
                human.connect(i, ch);

    human.dfsTree();human.buildSt();
    werewolf.dfsTree();werewolf.buildSt();
    
    // [type, yl, yr, idx]
	const int MX = 1e6;
    vector<array<int, 4>> evts[MX];
	for (int i = 1; i <= N; i++)
        evts[human.dt[i]+1].push_back({-2, werewolf.dt[i], 0, 0});
    for (int i = 0; i < Q; i++) {
        int u = human.findCompGeqMn(S[i], L[i]); // [L...N]
        int v = werewolf.findCompLeqMx(E[i], R[i]); // [1...R]
        evts[human.dt[i]].push_back({-1, werewolf.dt[i], werewolf.ft[i], i});
        evts[human.ft[i]+1].push_back({1, werewolf.dt[i], werewolf.ft[i], i});
    }


    vector<int> sol(Q);
    for (int i = 0; i < MX; i++) {
		for (auto [type,a,b,idx] : evts[i]) {
			if (type == -2) {
				update(a);
			} else {
				//cerr << i << ' ' << a << ' ' << b << endl;
				sol[idx] += type * query(a, b);
			}
		}
	}
    for (int i = 0; i < Q; i++)
		sol[i] = !!sol[i];
    return sol;
}

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:163:13: warning: unused variable 'u' [-Wunused-variable]
  163 |         int u = human.findCompGeqMn(S[i], L[i]); // [L...N]
      |             ^
werewolf.cpp:164:13: warning: unused variable 'v' [-Wunused-variable]
  164 |         int v = werewolf.findCompLeqMx(E[i], R[i]); // [1...R]
      |             ^
# 결과 실행 시간 메모리 Grader output
1 Incorrect 80 ms 171600 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 80 ms 171600 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 582 ms 228748 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 80 ms 171600 KB Output isn't correct
2 Halted 0 ms 0 KB -