一些注意点:
-
一看到这种题就应该往 bitset 的方向想。
-
如果用 bitset,就应该跳脱之前的思维,尝试从最朴素的暴力重新想起。
看到这道题,发现直接做非常的不可做的样子,考虑 bitset。
我们可以先枚举左端点 \(l\)。这样,当我们枚举 \(j\) 时,对于所有的 \(k\) 使得 \(a_{k, j} = a_{l, j}\) 的 \(k\),\((l, k)\) 可以多一个相等的下标。
于是考虑使用 bitset,\(p_{i, x, j}\) 表示 \(a_{i, j}\) 是否等于 \(x\)。然后直接异或操作即可。
/*******************************
| Author: DE_aemmprty
| Problem: F - Oddly Similar
| Contest: AtCoder - Toyota Programming Contest 2024#4(AtCoder Beginner Contest 348)
| URL: https://atcoder.jp/contests/abc348/tasks/abc348_f
| When: 2024-04-06 20:37:56
|
| Memory: 1024 MB
| Time: 2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
long long read() {
char c = getchar();
long long x = 0, p = 1;
while ((c < '0' || c > '9') && c != '-') c = getchar();
if (c == '-') p = -1, c = getchar();
while (c >= '0' && c <= '9')
x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
return x * p;
}
const int N = 2007;
long long n, m, ans;
int a[N][N];
bitset <N> s[N][1007], res;
void solve() {
n = read(), m = read();
for (int i = 1; i <= n; i ++) for (int j = 1; j <= m; j ++) {
a[i][j] = read();
s[j][a[i][j]][i - 1] = 1;
}
for (int i = 1; i <= n; i ++) {
for (int j = 1; j <= n; j ++)
res[j - 1] = 0;
for (int j = 1; j <= m; j ++)
res ^= s[j][a[i][j]];
for (int j = i; j < n; j ++)
if (res[j]) ans ++;
}
cout << ans;
}
signed main() {
int t = 1;
while (t --) solve();
return 0;
}
标签:Contest,read,题解,long,bitset,ABC348F,getchar
From: https://www.cnblogs.com/aemmprty/p/18118007