这题憋了我好久,原来在网站上评测怎么也不过,今天重写了一遍,下了下官网上的数据来测,就这么过了~
这题主要就是每个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.