BZOJ2303: [Apio2011]方格染色

2303: [Apio2011]方格染色

Time Limit: 20 Sec  Memory Limit: 256 MB
Submit: 1927  Solved: 744
[Submit][Status][Discuss]

Description

Sam和他的妹妹Sara有一个包含n × m个方格的
表格。她们想要将其的每个方格都染成红色或蓝色。
出于个人喜好,他们想要表格中每个2 ×   2的方形区
域都包含奇数个(1 个或 3 个)红色方格。例如,右
图是一个合法的表格染色方案(在打印稿中,深色代
表蓝色,浅色代表红色) 。
可是昨天晚上,有人已经给表格中的一些方格染上了颜色!现在Sam和Sara
非常生气。不过,他们想要知道是否可能给剩下的方格染上颜色,使得整个表格
仍然满足她们的要求。如果可能的话,满足他们要求的染色方案数有多少呢?

Input

输入的第一行包含三个整数n, m和k,分别代表表格的行数、列数和已被染
色的方格数目。
之后的k行描述已被染色的方格。其中第 i行包含三个整数xi, yi和ci,分别
代表第 i 个已被染色的方格的行编号、列编号和颜色。ci为 1 表示方格被染成红
色,ci为 0表示方格被染成蓝色。

Output

输出一个整数,表示可能的染色方案数目 W 模 10^9得到的值。(也就是说,如果 W大于等于10^9,则输出 W被10^9除所得的余数)。

对于所有的测试数据,2 ≤ n, m ≤ 106
,0 ≤ k ≤ 10^6
,1 ≤ xi ≤ n,1 ≤ yi ≤ m。

Sample Input

3 4 3
2 2 1
1 2 0
2 3 1

Sample Output

8

HINT

数据为国内数据+国际数据+修正版

鸣谢GYZ

Source

【题解】

最近总是犯一些蠢到极点的错误。

不(非常)难得到g[1][1] ^ g[i][1] ^ g[1][j] ^ g[i][j] = [i mod 2 == 0 && j mod 2 == 0]

不(非常)难发现确定了第一列和第一行就确定了整个表格

于是我们可以枚举g]1][1]的状态,通过已知g[i][j]来判断g[1][j]和g[i][1]是否相等,这样形成了

若干组有且仅有两个选项的约束关系(自己与自己绑在一组也是),答案就是2^(num-1),因为1已经确定了

用加权并查集来维护,0为相等,1为不等

相等^相等=相等

不等^不等=相等

相等^不等=不等

是很好用的性质

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <queue>
 6 #include <vector>
 7 #define max(a, b) ((a) > (b) ? (a) : (b))
 8 #define min(a, b) ((a) < (b) ? (a) : (b))
 9
10 inline void read(long long &x)
11 {
12     x = 0;char ch = getchar(), c = ch;
13     while(ch < ‘0‘ || ch > ‘9‘)c = ch, ch = getchar();
14     while(ch <= ‘9‘ && ch >= ‘0‘)x = x * 10 + ch - ‘0‘, ch = getchar();
15     if(c == ‘-‘)x = -x;
16 }
17
18 const long long MAXN = 1000000 + 10;
19 const long long MAXM = 1000000 + 10;
20 const long long MAXK = 1000000 + 10;
21 const long long MOD = 1000000000;
22
23 long long n,m,ans1,ans2,k;
24 long long x[MAXK], y[MAXK], color[MAXK];
25 long long fa[MAXK << 1], w[MAXK << 1], ok;
26
27 //0相等,1不等
28 long long find(long long x)
29 {
30     if(x == fa[x])return x;
31     int f = find(fa[x]);
32     w[x] ^= w[fa[x]];
33     fa[x] = f;
34     return f;
35 }
36
37 long long pow(long long a, long long b)
38 {
39     long long r = 1, base = a % MOD;
40     for(;b;b >>= 1)
41     {
42         if(b & 1) r *= base, r %= MOD;
43         base *= base, base %= MOD;
44     }
45     return r % MOD;
46 }
47
48 long long solution()
49 {
50     for(register long long i = n + m + 10;i >= 1;-- i)fa[i] = i, w[i] = 0;
51     fa[n + 1] = 1;
52     register long long tmp,f1,f2,now = 0,a;
53     for(register long long i = 1;i <= k;++ i)
54     {
55         if(x[i] == 1 && y[i] == 1)continue;
56         if((x[i] & 1) || (y[i] & 1)) tmp = 0;
57         else tmp = 1;
58         tmp ^= (0 ^ color[i]);
59         f1 = find(x[i]), f2 = find(y[i] + n);
60         a = w[x[i]] ^ w[y[i] + n] ^ tmp;
61         if(f1 == f2 && a)return 0;
62         fa[f2] = f1, w[f2] = a;
63     }
64     for(register long long i = n + m;i >= 1;-- i)
65         if(fa[i] == i)++ now;
66     return pow(2, now - 1);
67 }
68
69 int main()
70 {
71     read(n), read(m), read(k);
72     for(register long long i = 1;i <= k;++ i)
73     {
74         read(x[i]), read(y[i]), read(color[i]);
75         if(x[i] == 1 && y[i] == 1)
76             if(!color[i]) ok = 1;
77             else ok = 2;
78     }
79     ans1 = solution();
80     for(register long long i = 1;i <= k;++ i) color[i] ^= 1;
81     ans2 = solution();
82     if(ok == 1) ans2 = 0;
83     if(ok == 2) ans1 = 0;
84     printf("%lld", (ans1 + ans2) % MOD);
85     return 0;
86 }

BZOJ2303

时间: 2024-12-26 00:10:36

BZOJ2303: [Apio2011]方格染色的相关文章

bzoj 2303: [Apio2011]方格染色

传送门 Description Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 × 2的方形区域都包含奇数个(1 个或 3 个)红色方格.例如,右图是一个合法的表格染色方案(在打印稿中,深色代表蓝色,浅色代表红色) . 可是昨天晚上,有人已经给表格中的一些方格染上了颜色!现在Sam和Sara非常生气.不过,他们想要知道是否可能给剩下的方格染上颜色,使得整个表格仍然满足她们的要求.如果可能的话,满足他们要求的染色

BZOJ_2303_[Apio2011]方格染色 _并查集

Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好,他们想要表格中每个2 ×   2的方形区 域都包含奇数个(1 个或 3 个)红色方格.例如,右 图是一个合法的表格染色方案(在打印稿中,深色代 表蓝色,浅色代表红色) . 可是昨天晚上,有人已经给表格中的一些方格染上了颜色!现在Sam和Sara 非常生气.不过,他们想要知道是否可能给剩下的方格染上颜色,使得整个表格 仍然满足她们的要求.如果可能的话,满足他们

BZOJ 2303: [Apio2011]方格染色 题解

题目大意: 有n*m的方格,中间的数要么是1,要么是0,要求任意2*2的方格中的数异或和为1.已知一部分格子中的数,求合法的填数的方案数. 思路: 由题意得:a[i][j]^a[i][j+1]^a[i+1][j]^a[i+1][j+1]=1,令这个式子为S(i,j),那么对于某一格(i,j),我们把S(1,1)...S(i,j)异或起来,则可得当i,j均为偶数时a[1][1]^a[i][1]^a[1][j]^a[i][j]=1(于是为了方便先预处理一下),否则a[1][1]^a[i][1]^a[

【BZOJ2303】【Apio2011】方格染色 异或方程+并查集

链接: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/45081583"); } 题解: 首先我们发现对于 ai,j 有下列式子: ai,j xor ai+1,j xor ai,j+1 xor ai+1,j+1==1 然后推导得到对于 ai,j 有下列式子: a1,1 xor a1,j x

【bzoj 2303】【Apio2011】方格染色

题目: http://www.lydsy.com/JudgeOnline/problem.php?id=2303 题解: 很神奇的思路,膜一发大佬http://www.cnblogs.com/HHshy/p/5840018.html#undefined 设S(i,j)=a[i][j]^a[i+1][j]^a[i][j+1]^a[i+1][j+1].那么将S(1,1)^S(1,2)^...^S(1,j)^S(2,1)^...^S(2,j)^.....^S(i,j)展开,对于i相同的一行(如S(1,

BZOJ 2303 方格染色

首先考虑四个格子异或值为1. 然后(重点)发现每个格子的值只和最上面,最左边,和(1,1)的格子的颜色有关. 枚举(1,1)的颜色,联立方程,可以将未知数减少,那么并查集可做. 最后算答案的时候,有些连通块颜色确定,有些不确定,不确定的*2即可. 这题要注意细节!其实一开始的思路最不好想. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define max

code1744 方格染色

稍微复杂一点的划分dp 设f[i][j][k]为第i行前j个k次粉刷正确的最大值 由于每行循环使用,可以去掉第一维,但每次不要忘了清零(卡了好久) f[j][k]=max{ f[u][j-1] + max(u+1到j的蓝色的个数,u+1到j的红颜色的个数) } 设h[i][k]为第i行分成k份的最大值 h[i][k]=f[i][m][k] 设dp[i][k]为前i行总共分成k份的最大值 dp[i][k]=dp[i-1][t-x]+h[i][x] x表示在第i行使用x次 代码如下: #includ

[APIO2011]

来自FallDream的博客,未经允许,请勿转载,谢谢. ------------------------------------------------------ A.[Apio2011]方格染色 Sam和他的妹妹Sara有一个包含n × m个方格的表格.她们想要将其的每个方格都染成红色或蓝色.出于个人喜好,他们想要表格中每个2 ×   2的方形区域都包含奇数个(1 个或 3 个)红色方格.例如,右图是一个合法的表格染色方案(在打印稿中,深色代表蓝色,浅色代表红色) . 可是昨天晚上,有人已

做题单

错误 收藏了过多题目 QWQ P1383 高级打字机 P1270 “访问”美术馆 P1481 魔族密码 P1280 尼克的任务 P1271 聚会的快乐 P3631 [APIO2011]方格染色 P1243 排序集合 P2858 [USACO06FEB]奶牛零食Treats for the Cows P3146 [USACO16OPEN]248 P2890 [USACO07OPEN]便宜的回文Cheapest Palindrome P1896 [SCOI2005]互不侵犯 P3154 [CQOI2