1. 程式人生 > >POJ3274 – Gold Balanced Lineup

POJ3274 – Gold Balanced Lineup

///    看到網上全都是三個陣列  這裡用兩個就夠了
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<stack>
#define N 200000
#include<math.h>
#include<queue>
#define maxn  100000+5
#define mod 190401
using namespace std;
int n,k,linshi,ans;
int sum[maxn][32];
int cow[maxn][32];
vector<int>hs[mod];///   雜湊
bool eq(int a,int b){///    全等為真  否則假
for(int i=0;i<k;i++){
    if(sum[a][i]!=sum[b][i])return false;
}
return true;
}
int main(){
//freopen("input2.txt","r",stdin);
memset(cow,0,sizeof(cow));
cin>>n>>k;
ans=0;
for(int i=1;i<=n;i++){///  輸入
    scanf("%d",&linshi);
    for(int j=0;j<k;j++){
        cow[i][j]=linshi%2;
        linshi/=2;
    }
}
memset(sum,0,sizeof(sum));///  這裡作用就是把sum[0][i]都置零  區間的長度是可以從零點開始計算的
for(int i=1;i<=n;i++){
    for(int j=0;j<k;j++){
        sum[i][j]=sum[i-1][j]+cow[i][j];
    }
}
for(int i=0;i<=n;i++){///   壓縮操作並放入雜湊中
        int num=0;
    for(int j=k-1;j>=0;j--){
        sum[i][j]-=sum[i][0];
        num+=sum[i][j];
    }
    if(num<0)num=-num;
    num%=mod;
    hs[num].push_back(i);
}
for(int i=0;i<mod;i++){///  找到最長長度
    for(int j=0;j<hs[i].size();j++){
        for(int k=j+1;k<hs[i].size();k++){
            if(eq(hs[i][j],hs[i][k])){
                ans=max(ans,abs(hs[i][k]-hs[i][j]));
            }
        }
    }
}
cout<<ans<<endl;
return 0;
}