Apio-11-Color

這題憋了我好久,原來在網站上評測怎麼也不過,今天重寫了一遍,下了下官網上的數據來測,就這麼過了~
這題主要就是每個2*2的矩陣的xor值都是1,經過推導可以得到:
    g[1,1] xor g[1,b] xor g[a,1] xor g[a,b]=((a mod 2=0)and(b mod 2=0)) xor g[a,b];
由於兩個元素的xor值是可以傳遞的,然後就可以用並查集不斷的合併,
最後方案數即爲2^tot,(tot=連通分量的數量).
===================================================================

{
判斷(1,1)是否已經確定,若已確定且(1,1)=1,則將所有點的顏色取反;

初始化每一個集合,集合數爲tot=n+m-1;

對於任意的(a,b)=c,
 若(a=1)or(b=1)則(a,b)=c,
 否則,若((a mod 2=0)and(b mod 2=0))xor(c=1)則(1,b)xor(a,1)=1,
      否則(1,b)xor(a,1)=0;

每次合併兩個集合時,tot=tot-1,若出現矛盾則輸出0;

最後,答案爲(2^tot)mod(1000000000);
}
const red=2000001;
      blue=2000002;
var p,d:array[1..2000002] of longint;
    a,b,c:array[1..1000000] of longint;
    n,m,k,tot,i,ps,co,ans:longint;
procedure f(x:longint;var fx,dx:longint);
begin
     if p[x]=0 then begin
        fx:=x;
        dx:=0;
     end else begin
        f(p[x],fx,dx);
        p[x]:=fx;
        d[x]:=dx xor d[x];
        dx:=d[x];
     end;
end;
procedure union(a,b,dis:longint);
var fa,da,fb,db:longint;
begin
     f(a,fa,da);
     f(b,fb,db);

     if (fa=fb)and(da xor db<>dis)then begin
        write(0); close(input); close(output); halt;
     end;

     if fa<>fb then begin
        p[fa]:=fb;
        d[fa]:=da xor db xor dis;
        dec(tot);
     end;
end;
begin
     assign(input,'color.in'); reset(input);
     assign(output,'color.out'); rewrite(output);
     readln(n,m,k);
     ps:=2;
     for i:=1 to k do begin
         readln(a[i],b[i],c[i]);
         if (a[i]=1)and(b[i]=1)then
            if (co<>2)and(co<>c[i])then begin
               write(0);close(input);close(output); halt;
            end else co:=c[i];
     end;
     if co=1 then
     for i:=1 to k do c[i]:=1-c[i];
     fillchar(p,sizeof(p),0);
     fillchar(d,sizeof(d),0);
     union(red,blue,1);
     tot:=n+m-1;
     for i:=1 to k do begin
         //if (a[i]=0)or(b[i]=0)then continue;
         if a[i]=1 then if c[i]=1 then union(red,b[i],0) else union(blue,b[i],0)
         else if b[i]=1 then if c[i]=1 then union(red,m+a[i],0) else union(blue,m+a[i],0)
         else if ((a[i]mod 2=0)and(b[i]mod 2=0))xor(c[i]=1) then union(b[i],m+a[i],1) else union(b[i],m+a[i],0);
     end;
     ans:=1;
     for i:=1 to tot do ans:=(ans*2)mod 1000000000;
     writeln(ans);
     close(input); close(output);
end.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章