답안 #213377

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
213377 2020-03-25T16:24:28 Z Saboon Matching (COCI20_matching) C++14
58 / 110
1175 ms 524288 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int maxn = 100000 + 10;
const int maxl = 30;

struct point{
	int x, y;
} p[maxn];

struct segment{
	point a;
	point b;
	int i1, i2;
	segment(){
		i1 = i2 = -1;
	}
} s[maxn];

vector<int> vex[maxn], vey[maxn], vec[maxn], add[maxn], del[maxn];
int ask[maxn], cnt;
int lc[maxn * maxl], rc[maxn * maxl];
vector<int> g[maxn * maxl][2];
bool light[maxn][2];
int cmp[maxn * maxl], comp;
bool visited[maxn * maxl];

vector<int> topol;
void dfs(int v, bool w){
	visited[v] = 1;
	for (auto u : g[v][w])
		if (!visited[u])
			dfs(u, w);
	if (w == 0)
		topol.push_back(v);
	else
		cmp[v] = comp;
}

void scc(){
	int n = cnt;
	for (int i = 0; i < n; i++)
		if (!visited[i])
			dfs(i, 0);
	reverse(topol.begin(), topol.end());
	memset(visited, 0, sizeof visited);
	for (auto i : topol){
		if (!visited[i]){
			dfs(i, 1);
			comp ++;
		}
	}
}

void add_edge(int v, int u, bool type){ // type = 0 : v -> u, else v <- u
	if (type == 1)
		swap(v, u);
//	cout << "edge : " << v << " -> " << u << endl;
	g[v][0].push_back(u);
	g[u][1].push_back(v);
}

void get(int id, int L, int R, int l, int r, int v, bool type){
	if (r <= L or R <= l)
		return;
	if (l <= L and R <= r){
		add_edge(v, id, type);
		return;
	}
	int mid = (L + R) >> 1;
	get(lc[id], L, mid, l, r, v, type);
	get(rc[id], mid, R, l, r, v, type);
}

int change(int id, int L, int R, int idx, int v, bool type){
	if (idx < L or R <= idx)
		return id;
	int me = cnt ++;
	if (L + 1 == R){
		if (light[L][type] == 1)
			return me;
		add_edge(me, v, type);
		light[L][type] = 1;
		return me;
	}
	int mid = (L + R) >> 1;
	lc[me] = change(lc[id], L, mid, idx, v, type);
	rc[me] = change(rc[id], mid, R, idx, v, type);
	add_edge(me, lc[me], type), add_edge(me, rc[me], type);
	return me;
}

int build(int L, int R, bool type){
	int me = cnt ++;
	if (L + 1 == R)
		return me;
	int mid = (L + R) >> 1;
	lc[me] = build(L, mid, type);
	rc[me] = build(mid, R, type);
	add_edge(me, lc[me], type), add_edge(me, rc[me], type);
	return me;
}

int main(){
	ios_base::sync_with_stdio(false);
	int n;
	cin >> n;
	for (int i = 0; i < n; i++){
		cin >> p[i].x >> p[i].y;
		vex[p[i].x].push_back(i);
		vey[p[i].y].push_back(i);
	}
	int newint = 0;
	int N = 100000 + 1;
	for (int i = 1; i < N; i++){
		if (vex[i].size() == 2){
			segment me;
			me.a = p[vex[i][0]];
			me.b = p[vex[i][1]];
			me.i1 = vex[i][0];
			me.i2 = vex[i][1];
			vec[me.i1].push_back(newint);
			vec[me.i2].push_back(newint);
			s[newint++] = me;
		}
		if (vey[i].size() == 2){
			segment me;
			me.a = p[vey[i][0]];
			me.b = p[vey[i][1]];
			me.i1 = vey[i][0];
			me.i2 = vey[i][1];
			vec[me.i1].push_back(newint);
			vec[me.i2].push_back(newint);
			s[newint++] = me;
		}
	}
	int m = newint;
	memset(ask, -1, sizeof ask);
	for (int i = 0; i < m; i++){
		if (s[i].a.x != s[i].b.x){
			if (s[i].a.x > s[i].b.x){
				swap(s[i].a, s[i].b);
				swap(s[i].i1, s[i].i2);
			}
			add[s[i].a.x].push_back(i);
			add[s[i].b.x].push_back(i);
		}
		else
			ask[s[i].a.x] = i;
	}
	for (int i = 0; i < n; i++){
		if ((int)vec[i].size() == 0)
			return cout << "NE\n", 0;
		if ((int)vec[i].size() == 1){
			int v = vec[i][0];
			add_edge(2*v+1, 2*v+0, 0);
			continue;
		}
		int v = vec[i][0], u = vec[i][1];
		add_edge(2*v+1, 2*u+0, 0);
		add_edge(2*u+1, 2*v+0, 0);
		add_edge(2*v+0, 2*u+1, 0);
		add_edge(2*u+0, 2*v+1, 0);
	}
//	for (int i = 0; i < m; i++)
//		cout << "# " << i << " -> (" << s[i].a.x << " , " << s[i].a.y << ") - (" << s[i].b.x << " , " << s[i].b.y << ")" << endl; 
	cnt = 2*m;
	int r1 = build(1, N, 0);
	int r2 = build(1, N, 1);
	for (int i = 1; i < N; i++){
		if (ask[i] != -1){
			int idx = ask[i];
			int y1 = s[idx].a.y, y2 = s[idx].b.y;
			if (y1 > y2)
				swap(y1, y2);
			get(r1, 1, N, y1+1, y2, 2*idx+0, 0);
			get(r2, 1, N, y1+1, y2, 2*idx+1, 1);
//			cout << "Ask : " << idx << " : " << y1+1 << " - " << y2 << endl;
		}
		for (auto idx : add[i]){
//			cout << "Add or Remove : " << idx << " - " << s[idx].a.y << endl;
			r1 = change(r1, 1, N, s[idx].a.y, 2*idx+1, 0);
			r2 = change(r2, 1, N, s[idx].a.y, 2*idx+0, 1);
		}
	}
	scc();
	for (int i = 0; i < 2*m; i+=2)
		if (cmp[i] == cmp[i+1])
			return cout << "NE\n", 0;
	cout << "DA\n";
	for (int i = 0; i < m; i++)
		if (cmp[2*i+0] > cmp[2*i+1])
			cout << s[i].i1 + 1 << " " << s[i].i2 + 1 << '\n';
}
# 결과 실행 시간 메모리 Grader output
1 Correct 149 ms 184036 KB Output is correct
2 Correct 151 ms 184036 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 149 ms 184036 KB Output is correct
2 Correct 151 ms 184036 KB Output is correct
3 Correct 152 ms 184040 KB Output is correct
4 Correct 149 ms 184040 KB Output is correct
5 Correct 149 ms 184040 KB Output is correct
6 Correct 150 ms 184036 KB Output is correct
7 Correct 166 ms 184040 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 149 ms 184036 KB Output is correct
2 Correct 151 ms 184036 KB Output is correct
3 Correct 152 ms 184040 KB Output is correct
4 Correct 149 ms 184040 KB Output is correct
5 Correct 149 ms 184040 KB Output is correct
6 Correct 150 ms 184036 KB Output is correct
7 Correct 166 ms 184040 KB Output is correct
8 Correct 151 ms 184040 KB Output is correct
9 Correct 151 ms 184044 KB Output is correct
10 Correct 169 ms 184084 KB Output is correct
11 Correct 149 ms 184040 KB Output is correct
12 Correct 168 ms 184044 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 149 ms 184036 KB Output is correct
2 Correct 151 ms 184036 KB Output is correct
3 Correct 152 ms 184040 KB Output is correct
4 Correct 149 ms 184040 KB Output is correct
5 Correct 149 ms 184040 KB Output is correct
6 Correct 150 ms 184036 KB Output is correct
7 Correct 166 ms 184040 KB Output is correct
8 Correct 151 ms 184040 KB Output is correct
9 Correct 151 ms 184044 KB Output is correct
10 Correct 169 ms 184084 KB Output is correct
11 Correct 149 ms 184040 KB Output is correct
12 Correct 168 ms 184044 KB Output is correct
13 Correct 185 ms 190200 KB Output is correct
14 Correct 212 ms 190188 KB Output is correct
15 Correct 185 ms 190184 KB Output is correct
16 Correct 189 ms 190056 KB Output is correct
17 Correct 213 ms 190184 KB Output is correct
18 Correct 185 ms 190180 KB Output is correct
19 Correct 192 ms 190052 KB Output is correct
20 Correct 187 ms 190188 KB Output is correct
21 Correct 186 ms 190188 KB Output is correct
22 Correct 188 ms 190188 KB Output is correct
23 Correct 186 ms 190316 KB Output is correct
24 Correct 210 ms 190312 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 149 ms 184036 KB Output is correct
2 Correct 151 ms 184036 KB Output is correct
3 Correct 152 ms 184040 KB Output is correct
4 Correct 149 ms 184040 KB Output is correct
5 Correct 149 ms 184040 KB Output is correct
6 Correct 150 ms 184036 KB Output is correct
7 Correct 166 ms 184040 KB Output is correct
8 Correct 151 ms 184040 KB Output is correct
9 Correct 151 ms 184044 KB Output is correct
10 Correct 169 ms 184084 KB Output is correct
11 Correct 149 ms 184040 KB Output is correct
12 Correct 168 ms 184044 KB Output is correct
13 Correct 185 ms 190200 KB Output is correct
14 Correct 212 ms 190188 KB Output is correct
15 Correct 185 ms 190184 KB Output is correct
16 Correct 189 ms 190056 KB Output is correct
17 Correct 213 ms 190184 KB Output is correct
18 Correct 185 ms 190180 KB Output is correct
19 Correct 192 ms 190052 KB Output is correct
20 Correct 187 ms 190188 KB Output is correct
21 Correct 186 ms 190188 KB Output is correct
22 Correct 188 ms 190188 KB Output is correct
23 Correct 186 ms 190316 KB Output is correct
24 Correct 210 ms 190312 KB Output is correct
25 Runtime error 1175 ms 524288 KB Execution killed with signal 11 (could be triggered by violating memory limits)
26 Halted 0 ms 0 KB -