【题意】
在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.