改了一晚上才改对,疯了,没法说更多了
/* sum[i][j]代表0到i这个区间内 ,每位数的个数,j代表是第几位。
明显sum[a][j]-sum[b][j]中每个j都是相等时说明这个区间内是“平衡”的
所以可以用c[i][j]代表是否2者区间内是否平衡,c[i][j]=sum[i][j]-sum[i][0];
*/
#include<iostream>
#include<string>
#include<cmath>
#define M 100005
using namespace std;
int n,k,Max,flag,sum[M][32],c[M][32],vis[M];
struct COW
{
int v;
int p;
struct COW *next;
};
struct COW *hash[M];
void insert(struct COW *h,int i)
{
int m;
if(h->v==0)
{
h->v=1;
h->p=i;
h->next=new struct COW;
h->next->v=0;
}
else
{
int f=1;
for(int j=0;j<k;j++) //判断这个hash中是否有平衡区间,即二者的c全部相等的
if(c[i][j]!=c[h->p][j])
{
f=0;
break;
}
m=i-(h->p); //这个就是距离
if(f&&m>Max)
{
Max=m;
}
insert(h->next,i);
}
}
int main()
{
int i,j,x,m,key;
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&k);
for(j=0;j<k;j++) //给0初始化,i是从1开始的
{
sum[0][j]=0;
c[0][j]=0;
}
vis[0]=1; //往hash中插入0
hash[0]=new struct COW;
hash[0]->v=0;
hash[0]->next=NULL;
insert(hash[0],0);
Max=flag=0;
for(i=1;i<=n;i++)
{
scanf("%d",&x);
for(j=0;j<k;j++)
{
sum[i][j]=(x&1)+sum[i-1][j]; //位运算用在与二进制有关的题目真的非常好用!
/* 注意,x&1+1 =x&(1+1)*/
x=x>>1;
}
key=0;
for(m=0;m<k;m++)
{
c[i][m]=sum[i][m]-sum[i][0]; //算c
key+=c[i][m]*m; //hash的key值为c值*m的总和
}
key=abs(key);
key=key%M;
if(vis[key]==0)
{
vis[key]=1;
hash[key]=new struct COW;
hash[key]->v=0;
hash[key]->next=NULL;
}
insert(hash[key],i);
}
printf("%d\n",Max);
return 0;
}