求出前缀和,然后全部减去第一列。
将新的数列哈希求出最远的。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define maxn 100010
#define mod 100007
using namespace std;
int n,k;
int sum[maxn][35];
int c[maxn][35];
struct Hash
{
int dex;
int val;
}res;
vector <Hash> hash[mod];
int Abs(int x)
{
return x>0?x:-x;
}
bool same(int a,int b)
{
for(int i=1;i<=k;i++)
if(c[a][i] != c[b][i])return false;
return true;
}
int calhash(int index)
{
int val=0;
for(int i=1;i<=k;i++)
val+=c[index][i]*i;
return Abs(val)%mod;
}
int ans;
void insert(int v,int index)
{
int pos=v%mod;
int len=hash[pos].size();
for(int i=0;i<len;i++)
{
if(same(index,hash[pos][i].dex))
ans=max(ans,index-hash[pos][i].dex);
}
res.val=v,res.dex=index;
hash[pos].push_back(res);
}
int main()
{
while(scanf("%d%d",&n,&k)!=EOF)
{
ans=0;
for(int i=0;i<mod;i++)hash[i].clear();
for(int i=1,tmp,pos;i<=n;i++)
{
scanf("%d",&tmp),pos=1;
for(int j=1;j<=k;j++)sum[i][j]=sum[i-1][j];
while(tmp)
{
sum[i][pos++]+=tmp%2;
tmp/=2;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++)
c[i][j]=sum[i][j]-sum[i][1];
for(int i=0;i<=n;i++)
{
int v = calhash(i);
insert(v,i);
}
printf("%d\n",ans);
}
return 0;
}