首页 > 编程语言 >第45届国际大学生程序设计竞赛 亚洲区域赛(济南)A // 高斯消元

第45届国际大学生程序设计竞赛 亚洲区域赛(济南)A // 高斯消元

时间:2022-11-07 23:56:25浏览次数:62  
标签:01 int 45 矩阵 times 程序设计 未知量 高斯消

题目来源:第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(济南)A

题目链接:A-Matrix Equation


题意

定义01矩阵的两种运算:对于大小为 \(N \times N\) 的01矩阵 \(X\)、\(Y\),记 \(Z = X \times Y\),\(D = X \odot Y\),则有 \(Z_{i,j} = (\sum_{k=1}^{N}X_{i,k}Y_{k,j})\ mod\ 2\),\(D_{i,j} = X_{i,j}Y_{i,j}\).

对于给定的两个 \(N \times N\) 的01矩阵 \(A\)、\(B\),求有多少个 \(N \times N\) 的01矩阵 \(C\),满足 \(A \times C = B \odot C\),答案对 \(998244353\) 取模。

数据范围:\(1 \le N \le 200\),\(A_{i,j},B_{i,j} \in \{0,1\}\).

思路:高斯消元 + bitset优化

根据条件限制,可以得到 \(N \times N\) 个 含有 \(N \times N\) 个未知量的方程,未知量就是矩阵 \(C\) 的所有元素。

对方程组进行求解,每一个未知量要么是确定的值,要么是自由未知量,取值任意(可以任取 \(0/1\))。因此,若记自由未知量的个数为 \(cnt\),答案就是 \(\large 2^{cnt}\).

但是直接进行高斯消元的话,复杂度是 \(O(n^6)\),是无法接受的,需要进行优化。

观察限制条件的左右式子,可以发现,\(C\) 的不同列是相互独立的,因此可以考虑对 \(C\) 的每一列进行高斯消元,复杂度为 \(O(n·n^3)\) ,即\(O(n^4)\).

又因为矩阵元素的值只有 \(0\)、\(1\),因此可以用bitset进行优化,复杂度降为 \(O(n·{\large \frac{n^3}{\omega}})\),即 \(O({\large \frac{n^4}{\omega}})\),其中 \(\omega = 32\ or\ 64\),与机器有关。

代码

#include <bits/stdc++.h>
#define LL long long
using namespace std;

const int N = 210;
const int mod = 998244353;

int n, A[N][N], B[N][N];
bitset<N> b[N];

int gauss()
{
    int c, r;
    for(c = 1, r = 1; c <= n; ++ c) {
        int t = r;
        for(int i = r; i <= n && !b[t][c]; ++ i) t = i;
        if(!b[t][c]) continue;
        swap(b[r], b[t]);
        for(int i = r + 1; i <= n; ++ i) {
            if(b[i][c]) b[i] ^= b[r];
        }
        ++ r;
    }
    return n + 1 - r;
}

int qmi(int m, int k, int p)
{
    int res = 1;
    while(k) {
        if(k & 1) res = (LL)res * m % p;
        m = (LL)m * m % p;
        k >>= 1;
    }
    return res;
}

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    cin >> n;
    for(int i = 1; i <= n; ++ i) {
        for(int j = 1; j <= n; ++ j) cin >> A[i][j];
    }
    for(int i = 1; i <= n; ++ i) {
        for(int j = 1; j <= n; ++ j) cin >> B[i][j];
    }

    int cnt = 0;
    for(int j = 1; j <= n; ++ j) {
        for(int i = 1; i <= n; ++ i) b[i].reset();
        for(int i = 1; i <= n; ++ i) {
            for(int k = 1; k <= n; ++ k) b[i][k] = A[i][k];
            b[i][i] = b[i][i] ^ B[i][j];
        }
        cnt += gauss();
    }

    cout << qmi(2, cnt, mod) << endl;

    return 0;
}

标签:01,int,45,矩阵,times,程序设计,未知量,高斯消
From: https://www.cnblogs.com/jakon/p/16867933.html

相关文章

  • C语言程序设计(4)
    常见关键字auto,break,case,char,const,continue,default,do ,double,else,enum,externfloat,for,goto,int,long,register,return,sh......
  • 《Python程序设计——深入理解计算机系统的语言》上市了
    ​本书是为高校师生学习Python编程语言而设计编著的教材。全书分20章,其中包括:绪论;开发环境搭建;第一个Python程序;Python语法基础;数据类型;运算符;控制语句;数据结构;函数;面向对象......
  • 《Java程序设计——深入理解计算机系统的语言》上市了
    ​​​​本书是一部系统论述Java编程语言的体化教程(含纸质图书、教学课件、源代码与答疑服务)。书中主要内容包括:引言;开发环境搭建;第一个Java程序; Java语法基础;数据类型;运算......
  • 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明)
    比赛链接:https://ac.nowcoder.com/acm/contest/12548/H.HardCalculation思路:输出\(x\)+2020。代码:#include<bits/stdc++.h>usingnamespacestd;usingLL=l......
  • 45th ICPC昆明 C.Cities(区间dp)
    题目链接Description有n个点,每个点有自己的颜色(并且每种颜色出现次数不超过15次),每次操作可以把一段连续且颜色相同的点染成任意一种颜色,求把所有点染成相同颜色的最小操......
  • 第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(济南)
    比赛链接:https://ac.nowcoder.com/acm/contest/10662/C.StoneGame题意:有\(a1\)堆有1个石子的石堆,\(a2\)堆有两个石子的石堆,\(a3\)堆有三个石子的石堆。合并两......
  • CF1045G AI Robots (动态开点线段树 + 离散化)(关于其空间复杂度的分析)
    题目大意:火星上有\(N\)个机器人排成一行,第\(i\)个机器人的位置为\(x_i\),视野维\(r_i\),智商为\(q_i\)。我们认为第\(i\)个机器人可以看到的位置是\([x_i-r_i,......
  • P1455 搭配购买
    ​​传送门​​思路:用并查集将相同的云朵化为一个集合,并将一个集合内的所有云朵看作一个整体,最后用01背包得到答案。#include<bits/stdc++.h>usingnamespacestd;typedef......
  • 45. Jump Game II
    Youaregivena 0-indexed arrayofintegers nums oflength n.Youareinitiallypositionedat nums[0].Eachelement nums[i] representsthemaximumleng......
  • ybt 1459:friends
     写下一个字符串A,将其复制一遍得到B,在任意位置(包括首尾)插入一个字符得到C。现在你得到C。求出A 题意中的 [复制]:这个多余的字符在[1,md]或[md,n]枚举这个......