Codeforces 429E Points and Segments 欧拉回路

来源:互联网 发布:时时彩计划软件 编辑:程序博客网 时间:2024/06/07 13:24

E. Points and Segments
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Iahub isn't well prepared on geometry problems, but he heard that this year there will be a lot of geometry problems on the IOI selection camp. Scared, Iahub locked himself in the basement and started thinking of new problems of this kind. One of them is the following.

Iahub wants to draw n distinct segments [li, ri] on the OX axis. He can draw each segment with either red or blue. The drawing is good if and only if the following requirement is met: for each point x of the OXaxis consider all the segments that contains point x; suppose, that rx red segments and bx blue segments contain point x; for each point x inequality |rx - bx| ≤ 1 must be satisfied.

A segment [l, r] contains a point x if and only if l ≤ x ≤ r.

Iahub gives you the starting and ending points of all the segments. You have to find any good drawing for him.

Input

The first line of input contains integer n (1 ≤ n ≤ 105) — the number of segments. The i-th of the next nlines contains two integers li and ri (0 ≤ li ≤ ri ≤ 109) — the borders of the i-th segment.

It's guaranteed that all the segments are distinct.

Output

If there is no good drawing for a given test, output a single integer -1. Otherwise output n integers; each integer must be 0 or 1. The i-th number denotes the color of the i-th segment (0 is red and 1 is blue).

If there are multiple good drawings you can output any of them.

Examples
input
20 22 3
output
0 1
input
61 51 33 52 1011 1112 12
output
0 1 0 1 0 0


数轴上有很多区间。要求找到一种染色方案,给这些区间黑白染色,使得对于数轴上每个点,染黑的次数和染白的次数相差的绝对值不大于1.


把区间看做线段,区间的左、右界看做点,把右界+1,做欧拉回路。

把右界+1,是为了把闭区间[L,R]变为左闭右开[L,R+1),这样就不需要单独考虑右界的每个点。

为什么可以做欧拉回路?我们利用了欧拉回路的性质,把从左到右的边染黑,把从右向左的边染白,这样对于每个点,染色的数量总是平衡的。

如果图中不存在欧拉回路,我们就人为的把相邻的度数为奇数的点连起来,构造欧拉回路。存在回路之后,对于图中每个点,染黑的次数和染白的次数相等。把我们人为添加的边去掉,由于对于每个点至多多了一个覆盖它的区间,所以染黑的次数和染白的次数相差的绝对值至多为1,满足了题目的条件。


#include <cstdio>#include <iostream>#include <string.h>#include <string> #include <map>#include <queue>#include <deque>#include <vector>#include <set>#include <algorithm>#include <math.h>#include <cmath>#include <stack>#include <iomanip>#define mem0(a) memset(a,0,sizeof(a))#define meminf(a) memset(a,0x3f,sizeof(a))using namespace std;typedef long long ll;typedef long double ld;typedef double db;const int maxn=200005, inf=0x3f3f3f3f;const ll llinf=0x3f3f3f3f3f3f3f3f;const ld pi=acos(-1.0L);int l[maxn],r[maxn],col[maxn],a[maxn],head[maxn],d[maxn];bool use[maxn],visit[maxn];int num;struct Edge {int from,to,pre,id;};Edge edge[maxn*2];void addedge(int from,int to,int l) {edge[num]=(Edge){from,to,head[from],l};head[from]=num++;edge[num]=(Edge){to,from,head[to],l};head[to]=num++;}void dfs(int now) {visit[now]=1;for (int i=head[now];i!=-1;i=edge[i].pre) {if (use[i/2]) continue;use[i/2]=true;dfs(edge[i].to);if (edge[i].from<edge[i].to) col[edge[i].id]=0; else col[edge[i].id]=1;}}int main() {int n,i,j,m;num=0;memset(head,-1,sizeof(head));scanf("%d",&n);for (i=0;i<n;i++) {scanf("%d%d",&l[i],&r[i]);r[i]++;a[i*2]=l[i];a[i*2+1]=r[i];}sort(a,a+n*2);m=unique(a,a+n*2)-a;for (i=0;i<n;i++) {l[i]=lower_bound(a,a+m,l[i])-a;r[i]=lower_bound(a,a+m,r[i])-a;addedge(l[i],r[i],i);d[l[i]]++;d[r[i]]++;}int last=-1,ec=n;for (i=0;i<m;i++) {if (d[i]%2==1) {if (last!=-1) addedge(last,i,ec++),last=-1; else last=i;}}mem0(use);mem0(visit);for (i=0;i<m;i++) {if (!visit[i]) {visit[i]=1;dfs(i);}}for (i=0;i<n;i++) printf("%d ",col[i]);return 0;}


阅读全文
0 0
原创粉丝点击