[CF429E]Points ans Segments_欧拉回路

Points and Segments

题目链接:www.codeforces.com/contest/429/problem/E

注释:略。


题解

先离散化。

发现每个位置如果被偶数条线段覆盖的话那么这个位置上的线段两种颜色的个数是相等的也就是确定的。

如果是奇数的话,我们就强制再放一条线段覆盖这个位置,无论这条新加入线段的颜色,剩下的颜色个数也就确定了。

那么,每条线段只能有一种颜色,而且每个位置值为$0$。

我们想一个东西:欧拉回路。

发现欧拉回路其实要干的就是这事,所以我们暴力建图欧拉回路即可。

至于怎么想到欧拉回路这个东西.....看感觉吧......

代码

#include 

#define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout) 

#define N 1000010 

using namespace std;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ )

int rd() {
	int x = 0, f = 1;
	char c = nc();
	while (c < 48) {
		if (c == '-')
			f = -1;
		c = nc();
	}
	while (c > 47) {
		x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
	}
	return x * f;
}

int b[N];

struct Node {
	int x, y;
}a[N];

int head[N], to[N << 1], nxt[N << 1], tot = 1, id[N << 1], val[N << 1];

int ans[N];

inline void add(int x, int y, int z) {
	to[ ++ tot] = y;
	id[tot] = z;
	nxt[tot] = head[x];
	head[x] = tot;
}

bool vis[N];

int d[N];

void dfs(int p) {
	vis[p] = true;
	for (int i = head[p]; i; i = nxt[i]) {
		if (!val[i]) {
			val[i] = val[i ^ 1] = 1;
			if (p < to[i]) {
				ans[id[i]] = 1;
			}
			else {
				ans[id[i]] = 0;
			}
			dfs(to[i]);
		}
	}
}

int main() {
	setIO("party");
	int n = rd(), cnt = 0;
	for (int i = 1; i <= n; i ++ ) {
		a[i].x = rd(), a[i].y = rd() + 1;
		b[ ++ cnt] = a[i].x, b[ ++ cnt] = a[i].y;
	}
	sort(b + 1, b + cnt + 1);
	cnt = unique(b + 1, b + cnt + 1) - b - 1;
	// cout << cnt << endl ;
	for (int i = 1; i <= n; i ++ ) {
		a[i].x = lower_bound(b + 1, b + cnt + 1, a[i].x) - b;
		a[i].y = lower_bound(b + 1, b + cnt + 1, a[i].y) - b;
		add(a[i].x, a[i].y, i), add(a[i].y, a[i].x, i);
		d[a[i].x] ++ , d[a[i].y] ++ ;
	}

	// for (int i = 1; i <= n; i ++ ) {
	// 	printf("%d %d\n", a[i].x, a[i].y);
	// }

	int pre = 0;
	for (int i = 1; i <= cnt; i ++ ) {
		if (d[i] & 1) {
			if (!pre) {
				pre = i;
			}
			else {
				add(pre, i, 0), add(i, pre, 0);
				d[i] ++ , d[pre] ++ ;
				pre = 0;
			}
		}
	}

	for (int i = 1; i <= cnt; i ++ ) {
		if (!vis[i]) {
			dfs(i);
		}
	}

	for (int i = 1; i <= n; i ++ ) {
		printf("%d ", ans[i]);
	}
	fclose(stdin), fclose(stdout);
	return 0;
}

你可能感兴趣的:([CF429E]Points ans Segments_欧拉回路)