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.