F - Oddly Similar

F - Oddly Similar

Problem Statement

There are N sequences of length M, denoted as A1,A2,,AN. The i-th sequence is represented by M integers Ai,1,Ai,2,,Ai,M.

Two sequences X and Y of length M are said to be similar if and only if the number of indices i(1iM) such that Xi=Yi is odd.

Find the number of pairs of integers (i,j) satisfying 1i<jN such that Ai and Aj are similar.

Constraints

  • 1N2000
  • 1M2000
  • 1Ai,j999
  • All input values are integers.

Input

The input is given from Standard Input in the following format:

N M
A1,1 A1,2 A1,M
A2,1 A2,2 A2,M

AN,1 AN,2 AN,M

Output

Print the answer as an integer.


Sample Input 1

3 3
1 2 3
1 3 4
2 3 4

Sample Output 1

1

The pair (i,j)=(1,2) satisfies the condition because there is only one index k such that A1,k=A2,k, which is k=1.

The pairs (i,j)=(1,3),(2,3) do not satisfy the condition, making (1,2) the only pair that does.


Sample Input 2

6 5
8 27 27 10 24
27 8 2 4 5
15 27 26 17 24
27 27 27 27 27
27 7 22 11 27
19 27 27 27 27

Sample Output 2

5

 

解题思路

  纯暴力题,开优化甚至能在时限内跑 O(n2m) 的暴力。正解是用 std::bitset 优化到 O(nmnw)

  最暴力的做法是枚举当前行 i 和之前行 k<i,然后比较两行的元素。对于某一列 j,可以发现只有 ak,j=ai,j 的行 k 才会与第 i 行有相同的元素的贡献。所以对于第 i 行,当枚举到第 j 列时,我们希望能快速知道前面有哪些行 kak,j=ai,j

  只需开一个 std::bitset<n> 数组 st[j][x],表示前 i 行中,第 j 列有哪些行的值为 x,这些行用状态压缩来表示。因此在枚举到第 i 行时,用一个 std::bitset<n> 变量 t 来维护第 i 行与之前每一行相同元素数量的奇偶性,t 中的第 k 位表示第 i 行与第 k 行中相同元素数量的奇偶性。枚举每一列 j,并令 tst[j][ai,j]。最后 t1 的数量就是第 i 行与之前相同元素数量为奇数的行的数量。

  AC 代码如下,时间复杂度为 O(n2mw)

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

typedef long long LL;

const int N = 2005, M = 1005;

int a[N][N];
bitset<N> st[N][M];

int main() {
    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            scanf("%d", &a[i][j]);
        }
    }
    int ret = 0;
    for (int i = 0; i < n; i++) {
        bitset<N> t;
        for (int j = 0; j < m; j++) {
            t ^= st[j][a[i][j]];
        }
        ret += t.count();
        for (int j = 0; j < m; j++) {
            st[j][a[i][j]][i] = 1;
        }
    }
    printf("%d", ret);
    
    return 0;
}

 

参考资料

  AtCoder Beginner Contest 348:https://www.cnblogs.com/Lanly/p/18118195

posted @   onlyblues  阅读(58)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2021-04-08 用优先队列构造Huffman Tree及判断是否为最优编码的应用
2021-04-08 Huffman Codes
Web Analytics
点击右上角即可分享
微信分享提示