biology——并查集
烦人的生物(biology)
题目描述
最后一题了,当然是要让我们的jz出场了(jz就是zj,zj就是jz,至于为什么……&),处于某种ws的对知识的渴望,jz非常喜欢生物。
现在jz发现自己本身就是个非常纠结的动物,jz发现如果把自身的细胞排成一排,根据细胞某种性质的不同,可将细胞分成两类,如果将这两类细胞分别用0/1表示,就得到了一个能表示自身细胞的0/1串。jz发现了自身的0/1是个奇妙的东西,就决定出个题来恶心你。
他会告诉你自身0/1串的长度m,和给出你的描述0/1串的语句条数n。
每条语句都符合以下格式:
a, ,b, ,even/odd
表示自身 0/1串中第a~b位上数字的和是偶数/奇数
jz想让你说出最早出现的与前面描述矛盾的语句是谁,你能解决这个问题吗?
输入格式
第一行,一个整数m,表示jz自身0/1串的长度
第二行,一个整数n,表示jz给出的语句数目。
第三行~,共n行,为jz给出的语句,保证按上文所述格式给出。
输出格式
输出zj最早说出的与前面语句矛盾的语句的位置-1
Eg:如果该语句是第2句,输出1
如果没有矛盾,则输出n
样例输入
10
5
1 2 even
3 4 odd
5 6 even
1 6 even
7 10 odd
样例输出
3
数据范围
40% m<=1000000
100% m<=maxlongint
100% n<=5000
分析:
这道题,比较烦人了,
是一道那种点表示区间的题目。
并查集点们来判断给的条件是否正确。
每一个点,
拆成两个点来表示状态,
一种是偶的状态,一种是奇的状态,
用已知条件来判断矛盾。
program biology;
const
hashtmp:longint=8997;
con:longint=10000;
var
fa:array[0..20000]of longint;
hash:array[0..9000]of longint;
n,m,k,l,i,j,a,b:longint;
s:string;
function change(x:longint):longint;
var
t:longint;
begin
t:=x mod hashtmp;
if t<=0 then t:=t+hashtmp;
while (hash[t]<>-1)and(hash[t]<>x)do t:=(t+1)mod hashtmp;
hash[t]:=x;
exit(t);
end;
function getfa(x:longint):longint;
begin
if fa[x]=x then exit(x);
fa[x]:=getfa(fa[x]);
exit(fa[x]);
end;
procedure union(x,y:longint);
var
r1,r2:longint;
begin
r1:=getfa(x);
r2:=getfa(y);
if (r1<>r2) then fa[r1]:=r2;
end;
begin
assign(input,'biology.in');
reset(input);
assign(output,'biology.out');
rewrite(output);
readln(l);
readln(n);
for i:=1 to 20000 do fa[i]:=i;
for i:=1 to 9000 do hash[i]:=-1;
for i:=1 to n do
begin
read(a,b);readln(s);
a:=change(a-1);b:=change(b);
if s=' even' then
begin
if (getfa(a)=getfa(b+con))or(getfa(a+con)=getfa(b)) then
begin
writeln(i-1);
close(input);
close(output);
halt;
end;
union(a,b);
union(a+con,b+con);
end
else begin
if (getfa(a)=getfa(b))or(getfa(a+con)=getfa(b+con)) then
begin
writeln(i-1);
close(input);
close(output);
halt;
end;
union(a,b+con);
union(a+con,b);
end;
end;
writeln(n);
close(input);
close(output);
end.
浙公网安备 33010602011771号