poj1733

【题意】

在1~x的数轴上,整点上可能有一些人,现给出一些区间内有奇数还是偶数个人,问前多少个之间互不矛盾

【输入】

第一行x

第二行n

接下来n行形如a b odd或a b even

表示区间a到b之间有奇数或偶数个人

【输出】

一个整数,表示前多少项没有矛盾


并查集,设f[x]表示1~x的人数奇偶性,1为奇,0为偶

那么区间a b的奇偶性意义即为f[a-1] xor f[b]的值为0还是1

这个等于是个xor方程组,解的话n^3会超时

所以用并查集来搞,每个节点记住自己的父亲和与父亲的关系,利用压缩路径就可以在线性时间内求解


program poj1733;
type
  group=record
          father,relate:longint;
        end;
var
  tot,ans,n,i,j,k:longint;
  u,v:group;
  rel:string;
  space:char;
  father,change,p,x,y:array [0..5001] of longint;
  dl,new:array [0..10001] of longint;

procedure swap (var a,b:longint);inline;
begin
  if a=b then exit;
  b:=a xor b;
  a:=a xor b;
  b:=a xor b;
end;

procedure qsort (s,e:longint);
var
  i,j,k:longint;
begin
  if s>=e then exit;
  i:=s;
  j:=e;
  k:=dl[(s+e) div 2];
  while i<=j do
    begin
      while dl[i]<k do inc(i);
      while dl[j]>k do dec(j);
      if i>j then break;
      swap(dl[i],dl[j]);
      inc(i);
      dec(j);
    end;
  qsort(s,j);
  qsort(i,e);
end;

function find (now:longint):group;inline;
var
  ans:group;
begin
  if father[now]=0 then
    begin
      ans.father:=now;
      ans.relate:=0;
      exit(ans);
    end;
  ans:=find(father[now]);
  ans.relate:=ans.relate xor change[now];
  father[now]:=ans.father;
  change[now]:=ans.relate;
  exit(ans);
end;

function convert (now:longint):longint;inline;
var
  s,e:longint;
begin
  s:=1;
  e:=tot;
  while true do
    if new[(s+e) div 2]=now then exit((s+e) div 2)
                            else
    if new[(s+e) div 2]<now then s:=(s+e) div 2 + 1
                            else e:=(s+e) div 2 - 1;
end;

begin
  read(n);
  read(n);
  for i:=1 to n do
    begin
      read(x[i],y[i]);
      dec(x[i]);
      dl[i*2-1]:=x[i];
      dl[i*2]:=y[i];
      read(space);
      readln(rel);
      if rel='even' then p[i]:=0
                    else p[i]:=1;
    end;
  qsort(1,n*2);
  tot:=0;
  i:=1;
  while i<=n*2 do
    begin
      inc(tot);
      new[tot]:=dl[i];
      k:=i;
      while (i<=n*2)and(dl[i]=dl[k]) do inc(i);
    end;
  for i:=1 to n do
    begin
      x[i]:=convert(x[i]);
      y[i]:=convert(y[i]);
    end;
  ans:=n;
  for i:=1 to n do
    begin
      u:=find(x[i]);
      v:=find(y[i]);
      if u.father<>v.father then
        begin
          father[u.father]:=v.father;
          change[u.father]:=u.relate xor v.relate xor p[i];
        end
                            else
      if u.relate xor v.relate <> p[i] then
        begin
          ans:=i-1;
          break;
        end;
    end;
  writeln(ans);
end.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值