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.

posted on 2011-10-27 07:39  codeway3  阅读(357)  评论(0编辑  收藏  举报

导航