zoukankan      html  css  js  c++  java
  • 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为不等

    合并时先find两个元素,使之在两代表元素的下面,然后根据关系合并

    相等^相等=相等

    不等^不等=相等

    相等^不等=不等

    是很好用的性质

     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

     

  • 相关阅读:
    2020-2021第一学期《网络空间安全导论》第十周自习总结
    2020-2021第一学期2024"DCDD"小组第九周讨论
    2020-2021第一学期《网络空间安全导论》第九周自习总结
    2020-2021第一学期2024"DCDD"小组第八周讨论
    2020-2021第一学期20202411《网络空间安全导论》第八周自习总结
    2020-2021第一学期2024"DCDD"小组第七周讨论
    2020-2021第一学期《计算机科学概论》第七周自习总结
    2020-2021第一学期2024"DCDD"小组第七周讨论
    2020-2021第一学期《计算机科学概论》第六周自习总结
    2020-2021第一学期20202411欧几里得算法
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7476585.html
Copyright © 2011-2022 走看看