这题,首先,需要将每个数都转成二进制的。
对于每个二进制,做一遍前缀和,作为a[i][j]。
对于每一个a[i][j],减去a[i][1],这样子,如果a[x][j]==a[y][j](j=1...m)都相等。
那么这就是一对可行解。
对于每一个a[i][1...n]将其哈希。即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 inline int read(){ 7 int num=0,t=1;char c=getchar(); 8 while(c>'9'||c<'0'){if(c=='-')t=-1;c=getchar();} 9 while(c<='9'&&c>='0'){num=(num<<1)+(num<<3)+c-'0';c=getchar();} 10 return num*t; 11 } 12 const int mod=1000007,N=100010; 13 int a[N][33],ans=0,m,n,cnt=0; 14 int ha[mod],g[N][33],nxt[N],fir[N]; 15 void ins(int x,int y){ 16 for(int i=ha[x];;i=nxt[i]) 17 if(!i){ 18 nxt[++cnt]=ha[x];ha[x]=cnt;fir[cnt]=y; 19 for(int j=1;j<=m;j++)g[cnt][j]=a[y][j]; 20 break; 21 } 22 else{ 23 int j; 24 for(j=1;j<=m;j++)if(g[i][j]!=a[y][j])break; 25 if(j>m)break; 26 } 27 } 28 int find(int x,int y){ 29 for(int i=ha[x];i;i=nxt[i]){ 30 int j; 31 for(j=1;j<=m;j++)if(g[i][j]!=a[y][j])break; 32 if(j>m)return y-fir[i]; 33 } 34 return 0; 35 } 36 int main() 37 { 38 n=read();m=read(); 39 for(int i=1;i<=n;i++){ 40 int x=read(); 41 for(int j=1;j<=m;j++) 42 a[i][j]=a[i-1][j]+((x>>(j-1))&1); 43 for(int j=m;j>=1;j--) 44 a[i][j]-=a[i][1]; 45 } 46 ins(0,0); 47 for(int i=1;i<=n;i++){ 48 int tot=0; 49 for(int j=1;j<=m;j++)tot=(tot+(a[i][j]%mod+mod)*j)%mod; 50 ins(tot,i);ans=max(ans,find(tot,i)); 51 } 52 printf("%d",ans); 53 return 0; 54 }
注意,对于第43行的for循环,为什么要倒着做呢?因为,如果a[i][1]先减完之后,变成0了,可是呢,这样使得a[i][j](j>1)的值都不会更改。
本文由Yzyet编写,网址为www.cnblogs.com/Yzyet。非Yzyet同意,禁止转载,侵权者必究。