#include<iostream>
#include<fstream>
using namespace std;
#define N 100003
int n,k,tmp,mask,sum,jump,res;
int arr[100005][35];
int h[N];
bool same;
int main(){
//streambuf *backup;
// ifstream fin;
// fin.open("data.in");
// backup = cin.rdbuf(); // back up cin's streambuf
// cin.rdbuf(fin.rdbuf()); // assign file's streambuf to cin
cin>>n>>k;
memset(arr,0,sizeof(arr));
memset(h,-1,sizeof(h));
for(int i=1;i<=n;i++){
cin>>tmp;
mask=1;
for(int j=0;j<k;j++){
if(tmp&mask){
arr[i][j]=arr[i-1][j]+1;
}else{
arr[i][j]=arr[i-1][j];
}
mask=(mask<<1);
}
}
for(int i=1;i<=n;i++){
tmp = arr[i][0];
for(int j=0;j<k;j++){
arr[i][j]=arr[i][j]-tmp;
}
}
res=0;
for(int i=0;i<=n;i++){
sum=0;
for(int j=1;j<k;j++){
sum+=(arr[i][j]*j);
}
if(sum<0)
sum=-sum;
sum=sum%N;
jump=1;
same=false;
while(h[sum]!=-1){
same=true;
for(int j=1;j<k;j++){
if(arr[h[sum]][j]!=arr[i][j]){
same=false;
break;
}
}
if(same){
if(i-h[sum]>res){
res=i-h[sum];
}
break;
}else{
sum=sum+jump*jump;
sum=sum%N;
jump++;
}
}
if(!same){
h[sum]=i;
}
}
cout<<res<<endl;
return 0;
}
可以转化为数列相等问题
几个版本的hash
int hash(int x)
{
int sum=0;
for(int i=2;i<=k;++i){
sum*=ha;
sum+=a[x][i];
sum%=hm;
if(sum<0)sum+=hm;
}
return sum;
}
//hm=100003,ha=41
折叠法
inline int hashcode(const int *v)
{
int s = 0;
for(int i=0; i<k; i++)
s=((s<<2)+(v[i]>>4))^(v[i]<<10);
s = s % M;
s = s < 0 ? s + M : s;
return s;
}
UNIX下的字符串哈希函数
int ELFhash(char *key) /// 此乃UNIX系统使用的哈希,绝对有价值
{
unsigned long h = 0;
while (*key){
h = (h << 4) + *key++;
unsigned long g = h & 0xf0000000L; // 1个f,7个0
if (g) h ^= g >> 24;
h &= ~g;
}
return (h+M) % M; // M is Prime
}
int hashcode(const L&a) /// 把数字的转换为字符串,进行哈希,以后就不用费心思设计哈希了
{
char str[32*8];
char *s = (char*)(&a.d[1]);
int i;
for (i = 0; i < k-1; i++){
str[i] = 'a' + s[i];
}
str[i] = 0;
return ELFhash(str);
}