您的位置:首页 > 新闻 > 资讯 > P3631 [APIO2011] 方格染色

P3631 [APIO2011] 方格染色

2025/10/16 10:54:50 来源:https://blog.csdn.net/MC_wansui/article/details/141938834  浏览:    关键词:P3631 [APIO2011] 方格染色

~~~~~      P3631 [APIO2011] 方格染色 ~~~~~      总题单链接

思路

~~~~~       1 1 1表示红色, 0 0 0 表示蓝色, c o l [ i ] [ j ] col[i][j] col[i][j] 表示第 i i i 行,第 j j j 列的颜色。发现 i ≥ 2 , j ≥ 2 i\geq 2,j\geq 2 i2,j2 时, c o l [ i ] [ j ] = c o l [ i − 1 ] [ j − 1 ] ⊕ c o l [ i − 1 ] [ j ] ⊕ c o l [ i ] [ j − 1 ] ⊕ 1 col[i][j] = col[i-1][j-1]\oplus col[i-1][j]\oplus col[i][j-1]\oplus 1 col[i][j]=col[i1][j1]col[i1][j]col[i][j1]1,所以只要第一行和第一列的颜色确定了,整个矩阵就能确定。

~~~~~      但这还不够,先不管 ⊕ 1 \oplus 1 1 画个图看一下:

~~~~~      发现 a [ i ] [ j ] = a [ 1 ] [ 1 ] ⊕ a [ i ] [ 1 ] ⊕ a [ 1 ] [ j ] a[i][j]=a[1][1]\oplus a[i][1]\oplus a[1][j] a[i][j]=a[1][1]a[i][1]a[1][j],所以每次涂色等同于一个形如一个(若第 i i i行第一列的值是 a a a,则第 j j j 列第一行的值是 b b b)的限制,这里的 a , b ∈ { 0 , 1 } a,b \in{\{0,1\}} a,b{0,1},欸,那么 a [ 1 ] [ 1 ] a[1][1] a[1][1] 去哪了,仔细想想,假如这条限制默认 a [ 1 ] [ 1 ] = 0 a[1][1]=0 a[1][1]=0,那 a [ 1 ] [ 1 ] = 1 a[1][1]=1 a[1][1]=1 的情况不就是把 a , b a,b a,b 换一下吗,所以 a [ 1 ] [ 1 ] a[1][1] a[1][1] 在这条限制中其实不重要。

~~~~~      那么大概就可以往连边和连通块的方向去想了。

~~~~~      将每行每列视为两个点 u 0 u_0 u0 u 1 u_1 u1,表示这一行 / / /列的第一个值选 0 / 1 0/1 0/1

~~~~~      对于一次在第 i i i 行,第 j j j 列,颜色为 c c c 的涂色,设 u 0 , u 1 u_0,u_1 u0,u1 表示第 i i i 行表示的两个点, v 0 , v 1 v_0,v_1 v0,v1 表示第 j j j 列表示的两个点,连两条边 u 0 ——  v c , u 1 ——  v c ⊕ 1 u_0~——~v_c,u_1~——~v_{c\oplus 1} u0 —— vc,u1 —— vc1,连边后一个连通块就必须要一起选了,如果存在一个点使得 u 0 , u 1 u_0,u_1 u0,u1 在一个连通块中,那么答案就是 0 0 0

~~~~~      我们还没有考虑 ⊕ 1 \oplus 1 1,再画一个只考虑 ⊕ 1 \oplus 1 1的图:

~~~~~      发现只有 i , j i,j i,j 都为偶数的情况下才会 ⊕ 1 \oplus 1 1,直接将 c ⊕ 1 c\oplus 1 c1即可。

~~~~~      我个人认到这里还是比较难理解的,我也想了很久,所以如果你没有理解大可不必着急,慢慢来,再看一遍或者自己动手画图,模拟一下样例。

代码

#include<bits/stdc++.h>
#define ll long long
#define MOD 1000000000
using namespace std;inline ll qmi(ll a,ll b){ll res=1;while(b){if(b&1)(res*=a)%=MOD;(a*=a)%=MOD;b>>=1;}return res;
}ll n,m,Q;inline ll U(ll x,ll y){return(y==0?x:x+n);} 
inline ll V(ll x,ll y){return(y==0?x+n*2:x+n*2+m);}struct BJ{ll fas[400005],cnt;void init(){for(ll i=1;i<=2*(n+m);i++)fas[i]=i;cnt=2*(n+m);}inline ll fid(ll p){if(fas[p]!=p)fas[p]=fid(fas[p]);return fas[p];}inline void uni(ll x,ll y){x=fid(x),y=fid(y);if(x!=y)fas[x]=y,cnt--;}
}bj;signed main(){ios::sync_with_stdio(false);cin>>n>>m>>Q;if(n==1||m==1){cout<<qmi(2,n*m-Q);return 0;}bj.init();ll opt=1;while(Q--){ll x,y,c;cin>>x>>y>>c;if(x%2==0&&y%2==0)c^=1;bj.uni(U(x,0),V(y,c));bj.uni(U(x,1),V(y,c^1));if(bj.fid(U(x,0))==bj.fid(U(x,1))||bj.fid(V(y,0))==bj.fid(V(y,1)))opt=0;}cout<<(opt==1?qmi(2,bj.cnt/2-1):0)<<endl;return 0;
}

~~~~~      侵权必 … \ldots 算了都没人看,哪来的侵权。考虑给个赞和关注吗?

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com