• Yahoo Programming Contest 2019 E


    E - Odd Subrectangles

    链接

    题意:

      n*m的01矩阵,选出一些行和一些列,计算多少个选的方式,使得相交的点的权值和,是奇数,n,m<=300。

    分析:

      考虑选出了行,有多少列满足。

      把每一行的01序列看成一个二进制数,如果选出的行的异或起来是0,那么说明不论怎么选列的集合,都不能是奇数。如果异或起来不是0,那么选列的方案数是$2^{m-1}$。

      于是考虑多少种行的选法,使得异或起来不是0,线性基求出基的大小,设为cnt,那么$2^{n-cnt}$就是异或和为0的方案数,用总的减去,就是异或和不是0的方案数。

    代码:

    数组模拟:8ms

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 305, mod = 998244353;
    int a[N][N], b[N][N];
    
    int ksm(int a,int b) {
        int res = 1;
        while (b) {
            if (b & 1) res = 1ll * res * a % mod;
            a = 1ll * a * a % mod;
            b >>= 1;
        }
        return res;
    }
    
    int main() {
        int n = read(), m = read(), cnt = 0;
        for (int i = 1; i <= n; ++i) 
            for (int j = 1; j <= m; ++j) a[i][j] = read();
        for (int i = 1; i <= n; ++i) 
            for (int j = 1; j <= m; ++j) 
                if (a[i][j]) {
                    if (!b[j][j]) {
                        for (int k = j; k <= m; ++k) b[j][k] = a[i][k];
                        cnt ++;
                        break;
                    }
                    else {
                        for (int k = j; k <= m; ++k) a[i][k] ^= b[j][k];
                    }
                }
        cout << 1ll * (ksm(2, n) - ksm(2, n - cnt) + mod) % mod * ksm(2, m - 1) % mod;
        return 0;
    }
    View Code

    bitset优化:4ms

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
    #include<cmath>
    #include<cctype>
    #include<set>
    #include<queue>
    #include<vector>
    #include<map>
    #include<bitset>
    using namespace std;
    typedef long long LL;
    
    inline int read() {
        int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
        for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    }
    
    const int N = 305, mod = 998244353;
    bitset<N>a[N], b[N];
    
    int ksm(int a,int b) {
        int res = 1;
        while (b) {
            if (b & 1) res = 1ll * res * a % mod;
            a = 1ll * a * a % mod;
            b >>= 1;
        }
        return res;
    }
    
    int main() {
        int n = read(), m = read(), cnt = 0;
        for (int i = 1; i <= n; ++i) 
            for (int j = 1; j <= m; ++j) a[i][j] = read();
        for (int i = 1; i <= n; ++i) 
            for (int j = 1; j <= m; ++j) 
                if (a[i][j]) {
                    if (!b[j][j]) { 
                        b[j] = a[i];
                        cnt ++;
                        break;
                    }
                    else {
                        a[i] ^= b[j];
                    }
                }
        cout << 1ll * (ksm(2, n) - ksm(2, n - cnt) + mod) % mod * ksm(2, m - 1) % mod;
        return 0;
    }
    View Code
  • 相关阅读:
    如何在Windows Forms应用程序中实现可组装式(Composite)的架构以及松耦合事件机制
    SQL Server 2008中的CDC(Change Data Capture)功能使用及释疑
    【VSTO】Office开发中遇到的兼容性检查问题
    SQL Server 2008 R2的StreamInsight 【文章转载】
    WCF技术的不同应用场景及其实现分析
    如何利用Interception简化MVVM中的Model和ViewModel的设计
    有关在SharePoint Server中Infopath表单无法呈现的问题及解决方案
    再谈谈ADO.NET Data Service 数据格式(xml和json)
    自定义Domain Service时遇到实体不能更新的问题及其解决方案
    如何在RIA Service中启用身份验证
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10375337.html
Copyright © 2020-2023  润新知