A - Points and Segments CodeForces - 429E

题解:

方法非常巧妙的一道题

首先考虑要求全部为0怎么做

发现是个欧拉回路的问题(很巧妙)

直接dfs一遍就可以了

而这道题

要求是-1,1,0

我们可以先离散化

完了之后判断每个点被奇数还是偶数条边覆盖

如果是奇数,那么就多连一条边

另外有个细节是为了要用欧拉回路区间左开右闭

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=4e5;
const int INF=1e9+10;
int n,cnt[N],rd[N],b[N],head[N],l1;
struct re{
  int a,b,c,w;
}a[N],e[N*2];
bool cmp(re x,re y)
{
  return(x.a<y.a);
}
void arr(int x,int y)
{
  e[++l1].a=head[x];
  e[l1].b=y;
  head[x]=l1;
  e[l1].c=1;
  rd[x]++;
}
void dfs(int x)
{
  int u=head[x];
  while (u)
  {
    int v=e[u].b;
    if (e[u].c)
    {
      e[u].c=0; e[((u-1)^1)+1].c=0;
      if (x<v) e[u].w=1; else e[u].w=0;
      e[((u-1)^1)+1].w=e[u].w;
      dfs(v);
    }
    u=e[u].a;
  }
}
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  ios::sync_with_stdio(false);
  cin>>n;
  for (int i=1;i<=n;i++)
  { 
    int li,ri;
    cin>>li>>ri;
    a[i*2-1].a=li; a[i*2].a=ri;
    a[i*2-1].b=i*2-1; a[i*2].b=i*2;
  }
  sort(a+1,a+n*2+1,cmp);
  a[0].a=-INF; int l=0;
  for (int i=1;i<=n*2;i++)
  {
    if (a[i].a!=a[i-1].a) 
      if (a[i].a==a[i-1].a+1) l++;
      else l+=2;
    b[a[i].b]=l;
  }
  for (int i=1;i<=n;i++)
    cnt[b[i*2-1]]++,cnt[b[i*2]+1]--;
  int ans=0;
  for (int i=1;i<=l;i++)
  {
    ans+=cnt[i];
    if (ans%2) arr(i,i+1),arr(i+1,i);
  }
  int l2=l1+1;
  for (int i=1;i<=n;i++)
    arr(b[i*2-1],b[i*2]+1),arr(b[i*2]+1,b[i*2-1]);
  for (int i=1;i<=l;i++)
    if (rd[i]%2)
    {
      cout<<"-1";
      exit(0);
    }
  for (int i=1;i<=l+1;i++)
  {
    dfs(i);
  }
  while (l2<=l1)
  {
    cout<<e[l2].w<<" ";
    l2+=2;
  }
  return 0;
}

 

posted @ 2018-07-03 13:37  尹吴潇  阅读(178)  评论(0编辑  收藏  举报