#include <bits/stdc++.h> using namespace std; //用位存,比较的时候直接取反看是否相等,不要异或 //这是我的做法,超时了, //其实他用的是取反的技巧避免了第二重循环,那么就判断去饭后的结果在不在就可以了,用hash加速 // int n,m,a[50000],cache[50000];//cache 0 1 // int main(){ // cin>>n>>m; // memset(a,0,sizeof(a)); // memset(cache,0,sizeof(cache)); // int map=(1<<m)-1,s=0; // // cout<<map<<endl; // for(int i=0;i<n;i++){ // int k; // for(int j=0;j<m;j++){ // cin>>k; // a[i]=(a[i]<<1)+k; // } // } // // for(int i=0;i<n;i++){cout<<a[i]<<" ";} // // cout<<endl; // for(int i=0;i<n;i++){ // int temp=0,other=0,num=0; // //other 是累计减少 // if(cache[i]==1) continue; // for(int j=i+1;j<n;j++){ // // cout<<a[i]<<" "<<a[j]<<" "<<(a[i]^a[j])<<endl; // int r=a[i]^a[j]; // if(r==map) temp++;//注意!!!异或运算符优先级低,要打括号。 // //temp得到的是a[i+1]--a[j-1],即在相同之前的所有不同数 // else if(r==0){ // //说明a[j]和a[i]一样 // other+=temp; // num++; // cache[j]=1; // } // } // temp=temp*(num+1)-other; // s+=temp; // } // cout<<s<<endl; // return 0; // } //ans 为 对应的二进制转化后的值的个数 //把 On2 变成 On 了。。 int a[50000],ans[2000000],m,n; int main(){ cin>>n>>m; memset(a,0,sizeof(a)); memset(ans,0,sizeof(ans)); int map=(1<<m)-1,s=0; // cout<<map<<endl; for(int i=0;i<n;i++){ int k; for(int j=0;j<m;j++){ cin>>k; a[i]=(a[i]<<1)+k; } ans[a[i]]++; } for(int i=0;i<n;i++){ int k=a[i]^map;//相当于取反 s+=ans[k]; // int k=(~a[i]);这么做不可以,因为取反是针对于int全位的, // s+=ans[k]; //对 a[i] 取反后直接找对应的数目 } //这么做可以保证 1 2、 2 1都计算,所以除2 //我的方法中不能保证 cout<<s/2<<endl; return 0; }