poj1733

来源:互联网 发布:不用u盘安装ubuntu 编辑:程序博客网 时间:2024/04/30 13:14

【题意】

在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.


原创粉丝点击