题目
n(n<=2e3)行m(m<=2e3)列,第i行第j列的数a[i][j](1<=a[i][j]<=999)
称x行和y行这两行是相似的,当且仅当满足x[i]=y[i]的列有奇数个
统计i行和j行(i<=j)相似的对数(i,j),输出这个值
思路来源
Submission #52127725 - Toyota Programming Contest 2024#4(AtCoder Beginner Contest 348)
题解
注意到每次给在同一列里的相同的值一起操作,
相当于给这些行之前维护的奇偶性取反
给每一行维护一个bitset表示当前答案的奇偶性,
每次考虑每一列,给这一列每一个相同颜色维护一个bitset,
每次令每一行的当前答案,异或当前颜色的bitset即可
复杂度O(n*m*n/64)
代码
// Problem: F - Oddly Similar
// Contest: AtCoder - Toyota Programming Contest 2024#4(AtCoder Beginner Contest 348)
// URL: https://atcoder.jp/contests/abc348/tasks/abc348_f
// Memory Limit: 1024 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
typedef long long ll;
typedef double db;
typedef pair<ll,int> P;
#define fi first
#define se second
#define pb push_back
#define dbg(x) cerr<<(#x)<<":"<<x<<" ";
#define dbg2(x) cerr<<(#x)<<":"<<x<<endl;
#define SZ(a) (int)(a.size())
#define sci(a) scanf("%d",&(a))
#define scll(a) scanf("%lld",&(a))
#define pt(a) printf("%d",a);
#define pte(a) printf("%d\n",a)
#define ptlle(a) printf("%lld\n",a)
#define debug(...) fprintf(stderr, __VA_ARGS__)
const int N=2e3+5,M=1e3+5;
int n,m,a[N][N],sum;
bitset<N>ans[N];
void sol(){
sci(n),sci(m);
rep(i,1,n){
rep(j,1,m){
sci(a[i][j]);
}
}
rep(j,1,m){
bitset<N>b[M];
rep(i,1,n){
ans[i]^=b[a[i][j]];
b[a[i][j]][i]=1;
}
}
rep(i,1,n){
sum+=ans[i].count();
}
printf("%d\n",sum);
}
int main(){
sol();
return 0;
}