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.

你可能感兴趣的:(log)