vijos1112小胖的奇偶(并查集,区间转两端线段)

本文详细介绍了如何利用并查集解决Vijos1112问题,重点讨论了如何处理区间转化为两端线段的操作,并结合哈希技巧提高效率,为读者展示了一种巧妙的算法思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

program xiaopang;
const maxn=65533;//maxn最好大一点,65533可以
var father,hash:array[1..maxn shl 2]of longint;
    ch:char;
    l,i,x,y,n,ans:longint;
label 1;
function h(x:longint):longint; //hash,需要学习!注意数组也要定成1..maxn(开放寻址法)
var i:longint;
begin
 i:=x mod maxn;
 while (hash[i]<>-1)and(hash[i]<>x) do
  i:=i+1;
 hash[i]:=x;
 h:=i;
end;

function find(x:longint):longint;//本题在于变区间为1..i一组数的差的奇偶性问题,构造巧妙,合并不变
var t:longint;
begin
 if father[x]=x then exit(x);
 t:=father[x];      //凡找父亲一定要写路径压缩
 father[x]:=find(t);
 exit(father[x]);
end;
procedure union(x,y:longint);
var a,b:longint;
begin
 a:=find(x);
 b:=find(y);
 if a<>b then
  father[a]:=b;
end;
begin
 readln(l);
 readln(n);
 for i:=1 to maxn shl 2 do
  begin
   father[i]:=i;
   hash[i]:=-1;
  end;
 for i:=1 to n do
  begin
   readln(x,ch,y,ch,ch);
   x:=h(x-1);
   y:=h(y);
   if ch='e' then
    begin
     if find(x)=find(y+maxn) then
      begin
       writeln(ans);
       goto 1;//exit;
      end;
     union(x,y);
     union(x+maxn,y+maxn);//这里保证了判断矛盾时只要判断一种,应为两种一定同时存在或不存在
    end;
   if ch='o' then
    begin
     if find(x)=find(y) then
      begin
       writeln(ans);
       goto 1;//exit;
      end;
     union(x,y+maxn);
     union(x+maxn,y);
    end;
   ans:=ans+1;
  end;
 writeln(ans);
 1:
end.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值